控制器未走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 之类)。