Swift中的委托是什么?
在本文中,您将学习什么是委托以及它是如何工作的。
什么是委托?
顾名思义,委托将控制权赋予其他对象。为了实现这一点,必须将委托对象分配给控制其他对象。
在iOS应用程序中,UIApplicaitonDelegate就是一个例子。UIApplicationDelegate允许您修改iOS行为,例如接收推送通知、打开URL和启动应用程序。
委托模式确保需要委托的功能得到提供。
委托模式使对象能够与其所有者进行通信,而无需与其代码耦合。如果一个对象不必知道其所有者的具体类型,则代码更容易重用和维护。
Swift中的协议是什么?
协议充当一种工具,可以将属性和方法组合成一个单一实体,以便其他对象可以符合此协议来委托任务。
我们可以实现协议的属性和函数,这些属性和函数可以由Swift中的类、结构体或枚举提供。如果这些类型中的任何一个满足其要求,则称其符合协议。
创建协议的语法
语法
protocol <protocol_name> { // define the required methods here }
如上所示,我们为协议指定了一个协议名称,该名称使用Swift中的protocol关键字指定。通过根据协议的要求定义方法,您可以定义协议的目的。
创建委托对象
让我们尝试了解如何在ImageDownloader类中使用委托。我保留对委托对象(ImageDownloader类型)的一个可选引用,以允许ImageDownloader类实例在没有委托的情况下运行。如果委托成员变量为nil,ImageDownloader仍然下载文件,并仍然调用它自己的didDownloadImage()方法。
import UIKit class ImageDownloader { var urlString: String var downloadedImage: UIImage? var delegate: ImageDownloaderDelegate? init(_ urlString: String) { self.urlString = urlString } func downloadImage() // downloading image DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async { let imageURL = URL(string: self.urlString) let imageData = NSData(contentsOf: imageURL!) self.downloadedImage = UIImage(data: imageData! as Data) // update UI action on main thread DispatchQueue.main.async { self.didDownloadImage() } } } func didDownloadImage() { delegate?.didFinishDownloading(self) } }
创建协议
使用ImageDownloader类,我们将定义一个协议,以便在任务完成或失败时通知符合条件的对象。此协议将有一组规则(或函数)。
类、结构体或枚举可以符合协议并完成这些函数的实现。
在这个例子中,我们将使ProfileController类符合ImageDownloaderDelegate协议。现在,我们需要将委托对象设置为ProfileController的对象。
确保在ProfileController类中实现了所需的功能。否则,编译器将报告错误。
import UIKit // Protocol Creation protocol ImageDownloaderDelegate { // notify when downloading will be finished func didFinishDownloading(_ sender: ImageDownloader) // notify when downloading will be failed func didFailedDownloading(_ sender: ImageDownloader) }
符合此委托
现在,ProfileController类符合ImageDownloaderDelegate协议。
class ProfileController: UIViewController, ImageDownloaderDelegate { private var imageDownloader: ImageDownloader? private let profileImageView = UIImageView() override func viewDidLoad() { super.viewDidLoad() view.addSubview(profileImageView) // set profileImageView frame here as per requirement downloadImage() } private func downloadImage() { let imageURL: String = "<https://image_url_here>.com" imageDownloader = ImageDownloader(imageURL) imageDownloader?.delegate = self imageDownloader?.downloadImage() } func didFinishDownloading(_ sender: ImageDownloader) { profileImageView.image = sender.downloadedImage let urlString = sender.urlString print(urlString) } func didFailedDownloading(_ sender: ImageDownloader) { profileImageView.image = nil } }
如何创建可选协议方法?
您可以在协议中包含可选方法。您必须为可选协议方法创建一个扩展。
// protocol creation protocol ImageDownloaderDelegate { // notify when downloading will be finish func didFinishDownloading(_ sender: ImageDownloader) // notify when downloading will be failed func didFailedDownloading(_ sender: ImageDownloader) } extension ImageDownloaderDelegate { func didFailedDownloading(_ sender: ImageDownloader) { } }
结论
您可以将工作委托给其他人/其他事物来完成。委托帮助您分离关注点、解耦类并使代码更易于重用。使用委托的最佳起点是在您的视图和视图控制器之间。