前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >NSNotificationCenter.addObserverForName的正确打开方式

NSNotificationCenter.addObserverForName的正确打开方式

作者头像
码客说
发布2019-10-22 14:27:48
1.3K0
发布2019-10-22 14:27:48
举报
文章被收录于专栏:码客

前言

Apple 在 iOS4 中添加 addObserverForName 方法,给予开发者可以在block中处理 Notification 通知的便捷方法。

但是,在实际应用中,却比原有的 Selector 方法更复杂,甚至,一不小心就造成循环引用,内存得不到释放。

正文

这个方法的使用方法是这样的

代码语言:javascript
复制
class ViewController: UIViewController {
    weak var nameObserver: NSObjectProtocol?
    override func viewDidLoad() {
        super.viewDidLoad()
        nameObserver = NSNotificationCenter.defaultCenter().addObserverForName("Name", object: nil, queue: NSOperationQueue.mainQueue()) { (_) -> Void in
            print("some one call me!")
        }
    }
}

像上面这样使用,真是一点问题都没有! 但是,如果你要在block上使用self关键字的话,那就会造成循环引用(其实不算是循环引用,只要你在某个时间点,能把observer释放掉,也是OK的),这个ViewController永远不会被释放。

代码语言:javascript
复制
class ViewController: UIViewController {

    weak var nameObserver: NSObjectProtocol?

    deinit {
        print("dealloced") // 析构方法永远不会被执行
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        nameObserver = NSNotificationCenter.defaultCenter().addObserverForName("Name", object: nil, queue: NSOperationQueue.mainQueue()) { (_) -> Void in
            print("some one call me! -- view:\(self.view)")
        }
    }
}

解决方法很简单,使用weak self就可以了

代码语言:javascript
复制
class ViewController: UIViewController {

    weak var nameObserver: NSObjectProtocol?

    deinit {
        print("dealloced") // 这样就可以走到析构方法了
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        weak var welf = self
        nameObserver = NSNotificationCenter.defaultCenter().addObserverForName("Name", object: nil, queue: NSOperationQueue.mainQueue()) { (_) -> Void in
            if let welf = welf {
                print("some one call me! -- view:\(welf.view)")
            }
        }
    }
}

等等,你以为到这里,就结束了吗? 要记得,这个 Observer 其实还被 NSNotificationCenter 引用着,他也是不会释放的,最明显的体现就是,就算你的ViewController被释放了,block中的代码块仍然会被执行。

解决方法也很简单。

代码语言:javascript
复制
class ViewController: UIViewController {

    weak var nameObserver: NSObjectProtocol?

    deinit {
        if let nameObserver = nameObserver {
            NSNotificationCenter.defaultCenter().removeObserver(nameObserver) // 那我们就把它释放掉好了
        }
        print("dealloced") // 这样就可以走到析构方法了
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        weak var welf = self
        nameObserver = NSNotificationCenter.defaultCenter().addObserverForName("Name", object: nil, queue: NSOperationQueue.mainQueue()) { (_) -> Void in
            if let welf = welf {
                print("some one call me! -- view:\(welf.view)")
            }
        }
    }
}

本文转载自简书

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-07-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 正文
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档