dealloc 那些事

作者: 厨神小W空男子O | 来源:发表于2017-03-08 19:23 被阅读115次

控制器未走dealloc的原因:

(1).初始化的时候都是先调用父类的初始化方法,。 同样的情况可以在viewDidLoad中看到。而销毁的时候则是相反的顺序,先销毁子类里分配的空间,再销毁父类的。

(2).控制器中NSTimer没有被销毁

当viewController中存在NSTimer时,需要特别注意,当调用时,因为 target:self ,也就是引用了当前viewController,导致控制器的引用计数加1,如果没有将这个NSTimer 销毁,它将一直保留该viewController,无法释放,也就不会调用dealloc方法。所以,需要在viewWillDisappear之前需要把控制器用到的NSTimer销毁。

(补充,但是timer 会 retain target,不过 target 不一定是 self)

[timer invalidate];//销毁timertimer =nil;//置nil

(3).viewController中的代理不是weak属性

例如@property (nonatomic, weak) id delegate;代理要使用弱引用,因为自定义控件是加载在视图控制器中的,视图控制器view对自定义控件是强引用,如果代理属性设置为strong,则意味着delegate对视图控制器也进行了强引用,会造成循环引用。导致控制器无法被释放,最终导致内存泄漏。

(4).viewController中block的循环引用

在ARC下,block会把它里面的所有对象强引用,包括当前控制器self,因此有可能会出现循环引用的问题。比如viewController中有个block属性,在block中又强引用了self或者其他成员变量,那么这个viewController与自己的block属性就形成循环引用,导致viewController无法释放。(由于self是__strong修饰,在 ARC 下,当编译器自动将代码中的 block 从栈拷贝到堆时,block 会强引用和持有self,而self恰好也强引用和持有了 block,就造成了传说中的循环引用。)

dealloc里该写什么以及不该写什么:

(5).该写什么:从 NotificationCenter remove observer,remove KVO,有些非 ARC 管理的比如 CFRelease,有些流要关闭,用了 RAC 持有 disposable 对象的可以 dispose,这些都是比较常见的。还有一些会 removeGestureRecognizer,addToRunLoop 的 removeFromRunLoop,dispatch_release 掉自己持有的 queue,不过这些可能不是必要的。

(6).不该写什么:不要调 super dealloc,实际上想调也调不了…… ARC 下编译器会自动调的;在 init 方法和 dealloc 方法里都不要用点语法,而是直接用下划线 _property 进行存取。(因为点语法会触发 getter、setter 方法,不知道这些方法会被重写成什么,可能会涉及或者触发一些不该在 dealloc 阶段做的事比如 KVO 之类)。

相关文章

网友评论

    本文标题:dealloc 那些事

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