Swift中的Event Bus与观察者模式(iOS/macOS)
在iOS和macOS开发中,经常需要组织应用程序组件之间的松耦合交互。观察者模式及其以Event Bus(事件总线)形式的实现,是解决这一问题的强大工具。在本文中,我们将详细讲解如何使用Swift的现代特性(泛型、闭包、弱引用)来实现Event Bus。
什么是观察者模式?
观察者模式定义了对象之间"一对多"的关系。当一个对象(发布者)改变其状态时,所有依赖于它的对象(订阅者)都会自动收到通知并更新。这可以避免紧耦合,并简化代码维护。
在Swift中,原生的观察者模式实现包括:
NotificationCenter— Foundation内置的全局通知总线。- Key-Value Observing (KVO) — 观察对象属性的机制。
- Combine框架(iOS 13+)— 支持发布者和订阅者的响应式框架。
然而,在处理遗留代码或Combine不可用的项目中,通常需要更轻量且类型安全的实现。
Event Bus:简单而灵活的实现
Event Bus是一个中央事件调度器,允许订阅事件并发送事件,而无需直接了解订阅者。我们将使用泛型和弱引用来实现它,以避免内存泄漏。
Event Bus的基础实现
import Foundation
// 所有事件的协议protocol Event { }
// 具体的事件类型struct UserLoggedInEvent: Event { let userId: String let userName: String}
struct DataLoadedEvent: Event { let data: [String]}
// Event Bus类final class EventBus { static let shared = EventBus() private init() {} // 存储订阅者的字典 private var subscribers = [ObjectIdentifier: [Any]]() // 订阅事件 func subscribe<T: Event>(observer: AnyObject, handler: @escaping (T) -> Void) { let key = ObjectIdentifier(T.self) let wrapped = Subscription(observer: observer, handler: handler as Any) if subscribers[key] != nil { subscribers[key]?.append(wrapped) } else { subscribers[key] = [wrapped] } } // 取消特定观察者的所有事件订阅 func unsubscribe(observer: AnyObject) { for key in subscribers.keys { subscribers[key]?.removeAll(where: { subscription in if let sub = subscription as? Subscription { return sub.observer === observer } return false }) } } // 发布事件 func publish<T: Event>(event: T) { let key = ObjectIdentifier(T.self) guard let subs = subscribers[key] else { return } for subscription in subs { if let sub = subscription as? Subscription { if let handler = sub.handler as? (T) -> Void { handler(event) } } } }}
// 用于存储订阅的辅助结构private struct Subscription { weak var observer: AnyObject? let handler: Any init(observer: AnyObject, handler: Any) { self.observer = observer self.handler = handler }}使用Event Bus
// 订阅事件的ViewControllerclass LoginViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() // 订阅事件