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进行弱引用再使用。

上一篇下一篇

猜你喜欢

热点阅读