【问题标题】:For one-to-few relationships: NotificationCenter or multicasting delegate?对于一对多关系:NotificationCenter 还是多播委托?
【发布时间】:2019-04-18 21:20:38
【问题描述】:
【问题讨论】:
标签:
ios
swift
delegates
nsnotificationcenter
【解决方案1】:
我不会使用NotificationCenter,因为消息的类型以及发送者和接收者(观察者)之间的数据会丢失。使用Notification Center 将使您的代码依赖于Notification 对象,您需要使用通知的userInfo 字典来添加数据,这使得更难理解究竟是什么保留了通知(需要了解发送通知时会填充数据)。
委托是一个更好的解决方案,在弱委托列表中拥有超过 1 个委托是可以的。我在很多地方都使用过这样的组合,我需要为特定事件注册超过 1 个侦听器并且工作得很好。
您可以一次创建委托集合,然后在代码中轻松地重用它。这是我的解决方案:
class WeakContainer {
private weak var value: AnyObject?
public init(value: AnyObject) {
self.value = value
}
func get() -> AnyObject? {
return self.value
}
}
class DelegatesCollection<T>: Sequence {
private lazy var weakDelegates = [WeakContainer]()
var delegates: [T] {
return self.weakDelegates.map() { $0.get() as! T }
}
var hasDelegates: Bool {
return !self.weakDelegates.isEmpty
}
init() { }
func add(delegate: T) {
var exists = false
for currentDelegate in self.weakDelegates {
if(currentDelegate.get() === (delegate as AnyObject)) {
exists = true
break
}
}
if(!exists) {
self.weakDelegates.append(WeakContainer(value: delegate as AnyObject))
}
}
func remove(delegate: T) {
var i = 0
for currentDelegate in self.weakDelegates {
if(currentDelegate.get() == nil || currentDelegate.get() === (delegate as AnyObject)) {
self.weakDelegates.remove(at: i)
break
}
i += 1
}
}
func makeIterator() -> IndexingIterator<[T]> {
return self.delegates.makeIterator()
}
}
我可以推测 Apple 框架仅使用单个委托,因为它是一个业务逻辑,当委托被调用时要执行什么操作。从 Apple 的角度来看,委托某些事件已经发生并让应用程序决定下一步做什么就足够了,因此在框架级别支持多个委托是没有意义的。