Bootstrap

ios通知的创建与移除_iOS 9+ NotificationCenter 还需要手动移除观察者吗?

简评:原文作者在 twitter 上发起了个提问:在 iOS 11,是否需要 unregister

block-basednotification center 观察者?因为苹果文档上对于这部分描述比较模糊,

文档 removeObserver(_:) 文档中显示 iOS9+ 不再需要。

但在 addObserver(forName:object:queue:using:) 上则显示需要手动调用。

评论中支持这两种观点的各占一半。

问题

这里 block-based API 指的的是 NotificationCenter 中注册一个函数,当触发通知时调用这个函数。代码如下:

class MyObserver {

var observation: Any? = nil

init() {

observation = NotificationCenter.default.addObserver(

forName: myNotification, object: nil, queue: nil) { notification in

print("Received\(notification.name.rawValue)")

}

}

}

现在问题是:当 observation销毁的时候(即 MyObserver销毁) NotificationCenter 是否会自动丢弃这个 callback block,并且停止通知。还是说必须手动调用

测试结果显示 selector-based API 和 block-based API 情况不太一样。

自动 remove Observer

我们还可以对 NotificationCenter 进行简单的封装,来避免每次都手动注销 Oberserver。代码如下:

/// Wraps the observer token received from

/// NotificationCenter.addObserver(forName:object:queue:using:)

/// and unregisters it in deinit.

final class NotificationToken: NSObject {

let notificationCenter: NotificationCenter

let token: Any

init(notificationCenter: NotificationCenter = .default, token: Any) {

self.notificationCenter = notificationCenter

self.token = token

}

deinit {

notificationCenter.removeObserver(token)

}

}

现在我们将 observer 封装在了 NotificationToken 中,在 NotificationToken 创建的时候添加 observer, 销毁前自动移除该 observer,这样我们就可以通过管理 NotificationToken 对象的生命周期来实现移除 observer 操作。使用的时候只需要把 NotificationToken 存在一个私有属性中,当持有 NotificationToken 的对象销毁的时候 NotificationToken 会自动移除内部的观察者(当然我们可以主动向该私有属性赋 nil 来移除 observer)。

极光日报,极光开发者旗下媒体。

每天导读三篇英文技术文章。

;