【问题标题】:NSNotification Observer Closure not removed when Observer is removed?NSNotification 观察者关闭时观察者被移除时没有被移除?
【发布时间】:2015-08-28 03:08:35
【问题描述】:

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

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

有谁知道为什么关闭仍在处理通知?

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

【问题讨论】:

    标签: ios swift


    【解决方案1】:

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

    【讨论】:

    • 次要更正:在将 observer 传递给 removeObserver(_:) 之前,您必须解包它,因为您将其声明为可选。
    • 啊,呃。没有看到它返回了一些东西。谢谢!我现在可以转换我的选择器了! (我讨厌选择器:P)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-17
    • 1970-01-01
    相关资源
    最近更新 更多