Я бы не стал использовать NotificationCenter
, поскольку тип сообщения и данные между отправителем и получателем (наблюдателем) теряются.Использование Notification Center
заставит ваш код полагаться на объект Notification
, где вам нужно использовать словарь уведомлений userInfo
для добавления данных, что затруднит понимание того, что именно содержит уведомление (нужно будет увидеть, насколько точноданные заполняются при отправке уведомления).
Делегат является лучшим решением, и если в слабом списке делегатов более 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, достаточно делегировать, что произошло какое-то событие, и оставить приложение, чтобы решить, что делать дальше, поэтому нет смысла поддерживать несколько делегатов на уровне платформы.