删除Observer时未删除NSNotification Observer Closure?

时间:2015-08-28 03:08:36

标签: ios swift

我在视图控制器中有以下代码来注册我的一个自定义通知。到目前为止,我一直使用选择器进行注册,但我认为我会尝试使用闭包,并注意到一些奇怪的东西。

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行。)

有谁知道闭包还在处理通知的原因?

是否会出现一种情况,你会在选择器上使用闭包(我更喜欢它们,因为它避免了魔术字符串)?

1 个答案:

答案 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)
}