swift中Notifation无法释放

新手上路,请多包涵

swift中这样写通知的监听方式,就没有办法释放掉。

 var observer: NSObjectProtocol? = {
        
        var token: NSObjectProtocol?
        
        token = NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "11"), object: nil, queue: nil) { (note) in
            
            print(Thread.current)
           
            NotificationCenter.default.removeObserver(token!)
            
        }
        
        
        return token
        
    }()
    
    deinit {

        NotificationCenter.default.removeObserver(observer!)
       
    }

我释放了2次,都没有办法成功释放掉,但是如果不使用这种方式,正常的在viewDidLoad里面写,就可以在deinit中成功释放掉?我想知道为什么这样写法没法释放

阅读 4.1k
4 个回答
✓ 已被采纳新手上路,请多包涵

问题解决,之前出现的问题是我在A控制器跳转到B控制器之前就先发送一个通知,结果进入B控制器第一次不会直接打印我通知里面的打印,后面返回再点击时候直接就打印我通知里面的内容,我以为通知没有释放掉,其实是因为模拟器速度太快,以及苹果的监听应该有个延迟时间,我把新建B控制器并且push延迟5秒执行后一切打印正常,说明代码本身没有问题

你可以在 deinit 中打个断点,看看是否有走到。很可能的原因是 notification 持有了当前对象(self),导致当前对象无法 deinit,进而 removeObserver 的代码根本就没有走到。

尝试用 Xcode 的 Memory Graph 检查看看。

token = NotificationCenter.default.addObserver(forName: NSNotification.Name(rawValue: "11"), object: nil, queue: nil) { (note) in
    print(Thread.current)
    NotificationCenter.default.removeObserver(token!)         
 }

NotificationCenter.default.removeObserver(token!)

会导致NotificationCenter持有observer

闭包会捕获并持有外部变量。可以参考一下OCblock相关的知识。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进