当Observer被删除时,NSNotification Observer Closure不会被删除?
问题描述:
我在视图控制器中有以下代码来注册我的一个自定义通知。我已经使用选择器直到现在注册,但认为我会尝试关闭,并注意到一些奇怪的东西。当Observer被删除时,NSNotification Observer Closure不会被删除?
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行仍然被调用)。
有谁知道为什么封闭仍然处理通知?
会不会有一种情况,你会使用选择器上的闭包(我更喜欢它们,因为它避免了魔法字符串)?
答
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)
}
稍作修改:在将它传递给'removeObserver(_ :)'之前,必须展开'observer',因为您声明它是可选的。 –
哎呀,好的。谢谢。 – jtbandes
啊,呵呵。没有看到它返回的东西。谢谢!我现在可以转换我的选择器! (我讨厌选择器:P) – lionpants