30.在dealloc方法中只释放引用并解除监听
- 在dealloc方法里,应该做的事情就是释放指向其他对象的引用,并取消原来订阅的“键值观测”或NSNotificationCenter等通知,不要做其他的事情。
- 如果对象持有文件描述符等系统资源,那么应该专门编写一个方法来释放这些资源。这样的类,要和其他的使用者约定:用完资源后必须调用close方法。
- 执行异步任务的方法不应该在dealloc里调用;只能在正常状态下执行的那些方法也不应该在dealloc里调用,因为此时对象已经处于正在回收的状态了。
31.编写“异常安全代码”时留意内存管理问题
- 捕获异常时,一定要注意将try块内所创立的对象清理干净。
- 在默认情况下,ARC不生成安全处理异常所需的清理代码。开启编译器标志后,可声场这种代码,不过会导致应用程序变大,而且会降低运行效率。
32.保留环
- 即循环引用,请参考 (二十四)[Swift]循环引用,虽然是swift,原理是一样的
33.自动释放池
- 每个线程默认都会有自动释放池,每次执行事件循环都会将其清空
- 合理使用自动释放池,可以降低内存峰值,比如下面这两段代码的内存峰值是不一样的
//不用内存释放池
NSMutableArray *array = [NSMutableArray array];
for (int i=0; i<10000; i++) {
[array addObject:[NSString string]];
}
//使用内存释放池
NSMutableArray *array2= [NSMutableArray array];
for (int i=0; i<10000; i++) {
@autoreleasepool {
[array2 addObject:[NSString string]];
}
}
34.用僵尸对象调试内存管理问题
-
系统在回收对象时,可以不将其真的回收,而是把它转化为僵尸对象。通过下面这个方式开启僵尸对象
系统会修改isa指针,令其指向特殊的僵尸类,从而使该对象变为僵尸对象。僵尸类能够相应所有的选择子,响应方式为:打印一条包含消息内容及其接受者的消息,然后终止应用程序。
35.不要使用retainCount
- 对于保留计数看似有用,实则不然,因为任何给定时间点上的"绝对保留计数"都无法反映对象生命期的全貌
- 引入ARC之后,retainCount方法正是废纸,在ARC下调用该方法会导致编译器