我在视图控制器中有以下代码来注册我的一个自定义通知。到目前为止,我一直使用选择器进行注册,但我认为我会尝试使用闭包,并注意到一些奇怪的东西。
NSNotificationCenter.defaultCenter().addObserver(self, selector: "notificationReceived:", name: "NotificationKey", object: nil)
NSNotificationCenter.defaultCenter().addObserverForName("NotificationKey", object: nil, queue: nil) { [weak self] notification in
NSLog("Notification received in closure!")
}
@objc private func notificationReceived(notification: NSNotification) {
NSLog("Notification received!")
}
然后我以观察者的身份删除了视图控制器。
NSNotificationCenter.defaultCenter().removeObserver(self)
删除观察者后,我仍然在Closure中看到NSLog,但是我没有在选择器函数中看到NSLog。看来关闭是由通知中心保留的。我还注意到,如果在其中引用self,则闭包可能会导致保留周期(添加[weak self]修复此问题,但仍然会调用NSLog行。)
有谁知道闭包还在处理通知的原因?
是否会出现一种情况,你会在选择器上使用闭包(我更喜欢它们,因为它避免了魔术字符串)?
答案 0 :(得分:8)
addObserverForName(_:object:queue:usingBlock:)
实际上会返回一个可以保留的对象。这个对象应该传递给removeObserver()
。
var observer: AnyObject?
// ...
observer = NSNotificationCenter.defaultCenter().addObserverForName("NotificationKey", object: nil, queue: nil) { [weak self] notification in
NSLog("Notification received in closure!")
}
// ...
if let observer = observer {
NSNotificationCenter.defaultCenter().removeObserver(observer)
}