为什么你的Swift应用需要事件驱动架构?
想象一下,你是一位交响乐指挥家。每位乐手都在等待自己的乐谱部分,以便在合适的时机加入演奏。如果所有小提琴手同时演奏——那将是一片混乱。类似地,基于Swift的事件驱动架构也是这样工作的:每个模块只对特定事件做出响应,而不是直接去牵动其他模块的“线”。
当我第一次在商业项目中接触Swift事件驱动编程时,我意识到这是一个多么强大的工具。一个外卖应用:用户点击“下单”按钮——这是一个事件。购物车更新了——这是一个事件。收到骑手的推送——这是一个事件。每个模块(UI、网络、本地数据库)只需订阅相关事件并独立工作。这就是事件驱动架构。
在本文中,我们将探讨三种实现Swift事件架构的方法:经典的委托模式、NotificationCenter和自定义事件总线。你将看到真实代码,理解何时使用哪种方法,并能立即应用到自己的项目中。开始吧!
Swift中事件驱动方法的基础
在Swift上下文中什么是事件?
事件是一个信号,表明某事已经发生。它可以是:
- 用户输入(按钮被点击,文本被修改)
- 数据变化(从服务器获取数据,数据库更新)
- 系统通知(应用进入后台,键盘弹出)
Swift事件驱动架构的主要原则是松耦合(loose coupling)。事件的发送者不知道谁会处理它。接收者不知道是谁发送的。它们通过事件总线进行通信——这使得代码灵活且可测试。
Observer模式——事件的基础
Swift Observer模式是任何事件驱动系统的基础。我们有一个发布者对象(Publisher)和多个订阅者(Subscribers)。当发布者状态改变时,它会通知所有订阅者。
在Swift中,有几种内置机制可以实现这一点:
NotificationCenter——iOS SDK中的全局事件总线- 委托——一对一关系,但可控
Combine——Apple的响应式框架(iOS 13+)- 自定义实现——完全控制行为
让我们通过示例来逐一分析每种方法。
方法1:委托——经典之作
Swift委托是实现事件的最简单方式。它适用于“一对一”关系,即一个对象向另一个对象报告其状态。
示例:假设我们有一个图片加载器,需要通知控制器加载完成。
// 1. 定义委托协议protocol ImageLoaderDelegate: AnyObject { func imageLoader(_ loader: ImageLoader, didLoad image: UIImage) func imageLoader(_ loader: ImageLoader, didFailWith error: Error)}
// 2. 发布者类class ImageLoader { weak var delegate: ImageLoaderDelegate?
func loadImage(from url: URL) { URLSession.shared.dataTask(with: url) { [weak self] data, _, error in DispatchQueue.main.async { if let error = error { self?.delegate?.imageLoader(self!, didFailWith: error) } else if let data = data, let image = UIImage(data: data) { self?.delegate?.imageLoader(self!, didLoad: image) } } }.resume() }}
// 3. 订阅者控制器class ViewController: UIViewController, ImageLoaderDelegate { let loader = ImageLoader() @IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() { super.viewDidLoad() lo