是否删除了使用闭包语法创建的NotificationCenter观察器?

时间:2017-01-29 18:09:50

标签: swift nsnotificationcenter observers

我有一些使用块/尾随闭包语法创建的通知,如下所示:

NotificationCenter.default.addObserver(forName: .NSManagedObjectContextObjectsDidChange, object: moc, queue: nil) { note in
    // implementation
}

我之后删除了名字,如下:

NotificationCenter.default.removeObserver(self, name: NSNotification.Name.NSManagedObjectContextObjectsDidChange, object: moc)

我的问题

这是否足够?或者我是否绝对需要将NSObjectProtocol保存到它自己的属性并使用以下语法删除该属性?

NotificationCenter.default.removeObserver(didChangeNotification)

3 个答案:

答案 0 :(得分:10)

您绝对需要将返回值存储在属性中,稍后将其删除。

来自https://developer.apple.com/reference/foundation/nsnotificationcenter/1411723-addobserverforname

  

返回值

     

一个不透明的对象充当观察者。

当您调用任何一个removeObserver方法时,第一个参数是要删除的观察者。当您设置块以响应通知时,self 观察者,NSNotificationCenter在幕后创建自己的观察者对象并将其返回给您。

  

注意:从iOS 9开始,您不再需要从removeObserver / dealloc拨打deinit,因为这会在观察者时自动发生消失了。因此,如果您仅定位到iOS 9,这可能只是起作用,但如果您根本不保留返回的观察者,则可能会在您预期之前删除该通知。比抱歉更安全。

答案 1 :(得分:4)

要添加到@Dave的答案中,文档似乎并不总是100%准确。根据{{​​3}}的说法,文档中存在矛盾,并且自iOS {2.3起,this article by Ole Begemann中还没有发生过自动删除魔术。

因此答案仍然是“是,需要手动删除该观察者”(是的,自我不是观察者,addObserver()方法的结果是观察者)

答案 2 :(得分:0)

Here an example with code, for how a correct implementation looks like:

Declare the variable that gets returned when you add the observer in your class A (the receiver of the notification or observer):

private var fetchTripsNotification: NSObjectProtocol?

In your init method add yourself as an observer:

init() {
    fetchTripsNotification = NotificationCenter.default.addObserver(forName: .needsToFetchTrips, object: nil, queue: nil) { [weak self] _ in
        guard let `self` = self else {
            return
        }
        self.fetchTrips()
    }
}

In the deinit method of your class, make sure to remove the observer:

deinit { NotificationCenter.default.removeObserver(fetchTripsNotification as Any) }

In your class B (the poster of the notification) trigger the notification like usually:

NotificationCenter.default.post(name: .needsToFetchTrips, object: nil)