基于闭包的addObserver https://developer.apple.com/documentation/foundation/notificationcenter/1411723-addobserver
如果您使用基于闭包的addObserver 的变体,token (not self
) 是
观察者。通知中心根本不知道self
在这个情况下。该文档不是很清楚
这。
from Twitter https://twitter.com/olebegemann/status/1253006445295042565?s=20
这意味着这样做毫无意义:NotificationCenter.default.removeObserver(self)
The docs https://developer.apple.com/documentation/foundation/notificationcenter/1411723-addobserver推荐两种方式:
正常方式
像平常一样订阅:
let center = NSNotificationCenter.defaultCenter()
let mainQueue = NSOperationQueue.mainQueue()
self.localeChangeObserver = center.addObserverForName(NSCurrentLocaleDidChangeNotification, object: nil, queue: mainQueue) { (note) in
print("The user's locale changed to: \(NSLocale.currentLocale().localeIdentifier)")
}
在代码的某个点删除观察者。NotificationCenter.default.removeObserver(self.localeChangeObserver)
例如通过函数或在deinit
注意:您仍然需要使用[weak self]
以避免循环引用。
为了避免循环引用,请使用弱引用self
当在块内时self
包含观察者作为强参考。
单一订阅
第一次收到回调后立即删除观察者
let center = NSNotificationCenter.defaultCenter()
let mainQueue = NSOperationQueue.mainQueue()
var token: NSObjectProtocol?
token = center.addObserverForName("OneTimeNotification", object: nil, queue: mainQueue) { (note) in
print("Received the notification!")
center.removeObserver(token!)
}
基于选择器的addObserver https://developer.apple.com/documentation/foundation/notificationcenter/1415360-addobserver
如果您使用基于选择器的添加,self
(没有令牌)观察者。话虽如此,你应该avoid doing:
NotificationCenter.default.removeObserver(self)
因为您的代码可能不是唯一添加涉及该对象的观察者的代码。删除观察者时,请尽可能提供最具体的细节。例如,如果您使用名称和对象来注册观察者,请使用removeObserver(_:name:object:)
与名称和对象。
只有打电话才安全removeObserver(something)
in the deinit
方法,除此之外不要使用它使用removeObserver(_:name:object:)
反而。
Calling removeObserver(self)
外面不正确deinit
,因为您将删除为该对象设置的所有观察值。在里面调用它deinit
并不是不正确,而是毫无意义,因为该对象将立即被释放。