iOS开发中关于通知移除观察者的问题
2020-12-02 本文已影响0人
梁森的简书
iOS9之前
对于普通的添加观察者的方法
NotificationCenter.default.addObserver(self, selector: #selector(doSth(note:)), name: NSNotification.Name(rawValue: "ddd"), object: nil)
需要手动移除观察者self,因为iOS9之前NotificationCenter.default对self是unsafe_unretained引用,当self释放后,NotificationCenter.default持有的self并不会自动置为nil,而变成了一个野指针,这样再给self发送通知的话就会造成崩溃(给野指针发送消息)。
iOS9之后
对于普通的添加观察者的方法不需要手动移除观察者self,因为iOS9之后NotificationCenter.default对self是weak引用,当self释放后,NotificationCenter.default持有的self会自动置为nil,而给一个nil发送推送的时候是不会发生崩溃的。
使用selector方式添加观察者
iOS9之前需要手动移除观察者self,iOS9之后不需要手动移动观察者self。
使用闭包方式添加观察者
observation = NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "ddd"), object: nil, queue: .main) { (note) in
print("不能捕获self,全局变量NotificationCenter.default对self进行了强引用")
}
不管是iOS9之前还是iOS9之后我们都需要手动移除观察者,因为使用这种方式NotificationCenter.default对观察者进行的是强引用。
注意:
1.添加的观察者不是self,而是该方法返回的一个观察者,所以移除的时候要移除这个返回的观察者,否者即使当前self销毁了,该观察者还存在(被NotificationCenter强引用),在收到该通知后还会执行相应的方法。(swift中使用rxSwift就不用我们再手动移除该观察者了)
deinit {
print("被销毁了...")
NotificationCenter.default.removeObserver(observation as Any)
}
2.该方法会对self进行强引用,所以不要在block中直接使用self,否则会造成self无法释放,需要先对self进行弱引用再使用。