美文网首页
block的循环引用,导致页面pop后,不执行dealloc

block的循环引用,导致页面pop后,不执行dealloc

作者: 上路喽 | 来源:发表于2017-03-09 10:20 被阅读42次

今天在开发过程中,我发现工程里某个页面的通知(NSNotificationCenter)有时会被执行好几次。通知的使用是在viewDidLoad方法里注册,在dealloc方法中移除。按理来说,在viewcontroller的生命周期里这两个方法都只会执行一次,是相对应的,所以不应该存在通知被执行多次的情况。在排查后发现了原因:这个页面在被pop移出栈后没有被释放(即没有走dealloc方法)。

百度了pop移出栈后没有被释放的原因,归根结底,是因为当前控制器被某个对象强引用了,控制器的引用计数不为0,系统无法帮你释放这部分内存。大致分为以下几种情况

1.控制器中NSTimer没有被销毁

2.viewController中的代理不是weak属性

3.viewController中block的循环引用

对照以上情况和工程实际情况,前两种那个页面没有使用到,所以开始排查第三种情况。最终发现是解除循环引用用的是__block修饰,所以导致了pop后页面无法释放。

__block和__weak修饰符的区别:

1.__block不管是ARC还是MRC模式下都可以使用,可以修饰对象,还可以修饰基本数据类型。

2.__weak只能在ARC模式下使用,也只能修饰对象(NSString),不能修饰基本数据类型(int)。

3.__block对象可以在block中被重新赋值,__weak不可以。

4.__block对象在ARC下可能会导致循环引用,非ARC下会避免循环引用,__weak只在ARC下使用,可以避免循环引用。

最终,把__block改成__weak。

如果block没有直接或者间接被self存储,就不会产生循环引用,就不需要用weak self。在block里有时直接用self之类的强引用对象时,而系统没有警告,这不代表不会造成对象无法释放的情况。

只要你在block里用到了self所拥有的东西,都有可能造成循环引用,一定要注意!!!!!!!

相关文章

  • block的循环引用,导致页面pop后,不执行dealloc

    今天在开发过程中,我发现工程里某个页面的通知(NSNotificationCenter)有时会被执行好几次。通知的...

  • enum类型在block中的引用导致内存泄露

    今在使用block的时候莫名出现页面不走dealloc,特此记录,enum值在做实力变量的时候也是会导致循环引用,...

  • block循环引用释放不掉界面(dealloc不执行)

    上面{属性!!!} cell.answerToAnswerBlock = ^{__strong typeof(we...

  • 2018-04-29 iOS个人遇到的问题总结

    1. 粗心大意造成的循环引用 一开始发现页面通知的监听失效,后来发现页面pop关闭的时候dealloc方法也不调用...

  • iOS-循环引用

    如果一个控制器被循环引用了,那么这个控制器pop后不会调用dealloc方法,iOS中常见的循环引用以及解决方法如...

  • IOS内存优化

    问题1:多个页面无法成功dealloc,内存没有被释放.界面的循环引用问题问题2:某页面成功dealloc,但是仍...

  • 2019-03-02

    Block中避免循环引用方式 第一种也是大家最常用的 这种写法在block 未执行完成时候可能引用对象释,导致错误...

  • iOS - 性能优化

    内存方面 检测内存泄露 block使用上的强强循环导致页面不释放 :规范block使用,避免循环不释放 创建很多临...

  • IOS开发 日常踩坑记录

    Block 内部使用NSAssert导致的循环引用的问题

  • NSTimer循环引用

    NSTimer解决循环引用 这种写法 页面返回时,发现页面的dealloc没有调用,这是因为timer和VC相互调...

网友评论

      本文标题:block的循环引用,导致页面pop后,不执行dealloc

      本文链接:https://www.haomeiwen.com/subject/auqwgttx.html