我有一个自定义委托,用于触发某些事件。就上下文而言,它是一个可以任意触发事件的蓝牙设备。我希望我的视图控制器可以选择性地订阅这些由设备代理触发的事件。
每个视图控制器都符合自定义委托是没有意义的,因为这意味着设备变量将是本地的,并且只会在该视图控制器中激发。其他视图控制器不会意识到这一变化。另一个具体的例子是CLLocationManagerDelegate
——例如,如果我希望所有视图控制器都能监听GPS坐标的变化,该怎么办?
相反,我认为更多的是所有视图控制器都可以订阅的全局委托。因此,如果一个视图控制器触发请求,设备将为正在侦听的所有订阅的视图控制器调用委托函数。
我该如何实现这种建筑设计?学员的方法是否正确?我想也许NotificationCenter
可以在这方面有所帮助,但似乎类型太松散了,也许抛出协议会让事情变得更易于管理/更优雅?如有任何帮助,我们将不胜感激!
您可以拥有一个会收到通知的订阅者数组。
class CustomNotifier {
private var targets : [AnyObject] = [AnyObject]()
private var actions : [Selector] = [Selector]()
func addGlobalEventTarget(target: AnyObject, action: Selector) {
targets.append(target)
actions.append(action)
}
private func notifyEveryone () {
for index in 0 ..< targets.count {
if targets[index].respondsToSelector(actions[index]) {
targets[index].performSelector(actions[index])
}
}
}
}
当然,您必须进一步计划维护targets
和actions
的生命周期,并提供一种取消订阅等的方法。
注意:同样理想的情况是,目标和操作的数组是weak
对象中的一个。例如,这个SO问题涉及这个主题。
•NotificationCenter
是第一个想到的解决方案。是的,它是松散类型的。但是你可以改进它。例如:
extension NSNotificationCenter {
private let myCustomNotification = "MyCustomNotification"
func postMyCustomNotification() {
postNotification(myCustomNotification)
}
func addMyCustomNotificationObserverUsingBlock(block: () -> ()) -> NSObjectProtocol {
return addObserverForName(myCustomNotification, object: nil, queue: nil) { _ in
block()
}
}
}
•第二个解决方案是创建一些共享对象,它将存储所有委托或块/闭包,并在需要时触发它们。这样的对象基本上与使用NotificationCenter
相同,但提供了更多的控制。