if ([self shouldLogMessage]) {
NSString *message = [[NSString alloc] initWithFormat:@"I am object, %p", self];
NSLog(@"message = %@", message);
}
这段代码采用手动管理内存的方式,存在内存泄露的问题。if语句块末尾并没有释放message对象,由于在if语句之外无法引用message,所以此对象所占的内存泄漏了。if语句结束后,此对象将会永远存在无法释放。
判定内存泄漏的原则很简单,调用NSString的alloc方法所返回的那个message对象的保留计数比期望值要多1.但是没有与之对应的释放操作来抵消。很容易把这些规则应用到“静态分析器”上,用来分析程序内存泄漏的情况。
自动管理引用计数,可以于if结束前,自动对message对象进行释放操作。
if ([self shouldLogMessage]) {
NSString *message = [[NSString alloc] initWithFormat:@"I am object, %p", self];
NSLog(@"message = %@", message);
[message release] ///<< added by ARC
}
ARC会自动执行retain,release,autorelease,所以在ARC环境下调用这些方法是非法的,会产生编译错误。实际上ARC调用这些方法时并不通过OC的消息派发。直接调用底层的C语言,这样做性能更好,释放保留的操作需要频繁的执行,直接调用底层函数可以节省很多CPU周期。这也是不能覆写retain,release,autorelease这些方法的原因。
如果方法名以以下词语开头,返回的对象归调用者所有。
alloc,new,copy,mutableCopy,调用这些方法的那段代码要将其中一次保留计数抵消掉。
如果方法名不以上述四个词语开头,所返回的对象不归调用者所有,这种情况下,返回的对象会自动释放。要想使对象多存活一段时间,调用者必须主动保留它。
总结:
1.使用ARC之后,可以省去程序中的很多重复代码
2.ARC管理对象生命周期的办法基本是:在合适的地方自动插入“保留”及“释放”操作
3.由方法返回的对象,其内存管理语义是通过方法名来体现的