Swift 中的委托 (Delegate) 是什么?

swiftserver side programmingprogramming更新于 2025/10/10 12:22:17

在本文中,您将了解委托 (Delegate) 是什么以及它是如何工作的。

什么是委托 (Delegation)?

顾名思义,委托将控制权赋予其他对象。要实现委托,必须将委托对象分配给其他对象。

在 iOS 应用中,UIApplicaitonDelegate 就是一个例子。UIApplicationDelegate 允许您修改 iOS 行为,例如接收推送通知、打开 URL 和启动应用。

委托模式确保提供需要委托的功能。

委托模式使对象能够与其所有者进行通信,而无需与代码耦合。如果对象无需了解其所有者的具体类型,代码的重用和维护就会更加容易。

Swift 中的协议是什么?

协议充当一种工具,将属性和方法组合成一个实体,以便其他对象可以遵循该协议来委托任务。

我们可以实现 Swift 中类、结构体或枚举所提供的协议的属性和函数。如果这些类型中的任何一个满足协议的要求,则称该协议遵循该协议。

创建协议的语法

语法

protocol <protocol_name> {
    // 在此处定义所需的方法
}

如上所示,我们为协议指定了一个协议名称,该名称在 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) { } }

结论

您将工作委托给可以完成该工作的人/事物。委托可以帮助您分离关注点、解耦类并提高代码的可复用性。委托的最佳起点是视图和视图控制器之间。



相关文章



关于我们 | 隐私条款 | 学习路线
返回顶部