iOS 中控制器的释放问题

2015-10-14 21:42:15 +08:00
 tunnyios
![]( http://7xke07.com1.z0.glb.clouddn.com/2015-10-14-iOS-ViewControllerDealloc_blockCrash.JPG)

##**iOS 中控制器的释放问题**

ARC 工程是可以重写 dealloc 方法并被系统调用的,但不需要手动调用父类的 dealloc ,手写[super dealloc]方法会报错,事实上系统会自动帮你调用父类的 dealloc 方法,不需要你实现。可以通过在 dealloc 方法中打印 log 查看控制器是否被释放。

控制器在被 pop 后移出栈后会被释放,但有些时候会发现控制器出栈的时候不会调用 dealloc 方法,归根结底,是因为当前控制器被某个对象强引用了,控制器的引用计数不为 0 ,系统无法帮你释放这部分内存。

###**控制器中 NSTimer 没有被销毁**

当控制器中存在 NSTimer 时,就需要注意,因为当**[NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updateTime:) userInfo:nil repeats:YES];**时,这个 /*target:self*/ 就增加了 VC 的 RetarnCountr, 如果你不将这个 timer invalidate ,就别想调用 dealloc 。需要在 viewWillDisappear 之前需要把控制器用到的 NSTimer 销毁。

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

###**控制器中的代理不是 weak 属性**

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

###**控制器中 block 的循环引用**

block 会把它里面的所有对象强引用(在 ARC 下)/*PS:MRC 下会 retain 加 1*/,包括当前控制器 self ,因此有可能会出现循环引用的问题。
即一个对象有一个 Block 属性,然而这个 Block 属性中又引用了对象的其他成员变量,那么就会对这个变量本身产生强应用,那么这个对象本身和他自己的 Block 属性就形成了循环引用。在 ARC 下需要修改成这样:(/*也就是生成一个对自身对象的弱引用*/)

- __weak typeof(self) weakSelf = self;

**即:保险起见 block 中所有的涉及到 self 的全给替换成 weakSelf**

http://tunnyios.github.io/
2045 次点击
所在节点    iDev
0 条回复

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/228089

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX