简评:原文作者在 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)。
极光日报,极光开发者旗下媒体。
每天导读三篇英文技术文章。