内存管理
第29条:理解引用计数
Objective-C 语言使用引用计数器来管理内存,每个对象都有个可以递增或递减的计数器。对象创建好之后,其保留计数至少为1,若保留计数为正,则对象继续存活,当保留计数降为0时,对象被销毁。
在对象的生命周期中,其余对象通过引用来保留或释放此对象。保留或释放操作分别会递增或递减保留计数。
注意retain
,release
,autorelease
,这三个方法操作计数器。
第30条:以ARC简化引用计数
ARC,即自动管理计数器。
在ARC中,变量的内存管理语义可以通过修饰符指明,而原来则需手工执行”保留“及释放操作;(__strong
,__weak
,一个保留值,一个不保留值)。
注意的是ARC只负责管理Objective-C对象的内存。注意:CoreFoundation
对象不归ARC管理,必须适时调用CFRetain
/CFRelease
第31条:在dealloc中只释放引用并解除监听
- (void)dealloc
{
// CFRelease(COREFOUNDATIONObject);
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
第32条:编写”异常安全代码“时留意内存管理问题
@try {
// 可能会出现崩溃的代码
}
@catch (NSException *exception) {
// 捕获到的异常exception
}
@finally {
// 结果处理,也可以去掉
}
简单的来说,
Apple
虽然同时提供了错误处理NSError
)和异常处理(exception
)两种机制,但是Apple
更加提倡开发者使用NSError
来处理程序运行中可恢复的错误。而异常被推荐用来处理不可恢复的错误。
第33条:以弱引用避免保留环
保留环也就是我们常说的循环引用。就是有时候我们需要将某些引用设为
weak
,可避免出现“保留环”。
第34条:以”自动释放池块“降低内存峰值
自动释放池用于存放那些需要在稍后某个时刻释放的对象。
NSArray * dataRecord = /*****/;
NSMutableArray * testPeopleArray = [NSMutableArray array];
for(NSDictionary * recordDic in dataRecord)
{
TestPeople * people = [[TestPeople alloc] initWithRecord:recordDic];
[testPeopleArray addObject:people];
}
当循环长度无法预估,需要读出很多对象的时候,像上面中,会有一些临时对象产生,内存中会有很多不必要的临时对象,他们本该提早回收的,增加一个释放池就好啦。
NSArray * dataRecord = /*****/;
NSMutableArray * testPeopleArray = [NSMutableArray array];
for(NSDictionary * recordDic in dataRecord)
{
@autoreleasepool {
TestPeople * people = [[TestPeople alloc] initWithRecord:recordDic];
[testPeopleArray addObject:people];
}
}
注意不要把for
循环放到释放池里面,特别是循环长度特别长的时候。
第35条:用”僵尸对象“调试内存管理问题
启动这项调试功能之后,运行期系统会把所有已经回收的实例转化成特殊的“僵尸对象”,而不会真正的回收他们。这种对象所在的核心内存无法重用,因此不可能遭到覆写。僵尸对象收到消息后,会抛出异常,其中准确说明了发送过来的消息,并描述了回收之前的对象。
第36条:不要使用retainCount
对象的保留计数看似有用,实则不然,因为任何给定时间点上的“绝对保留技术”都无法反映对象的生命期的全貌。
但是这个其实我们一般也不会用,ARC环境下已经禁止啦。
持续记录中····