1、什么是ARC
顾名思义,自动引用计数是指内存管理中采用自动计数的技术。
苹果官方文档:在Obj-C中,采用ARC,让编译器进行内存管理,就无需键入release和retain相关代码,可以降低崩溃和内存泄露风险的同时,很大程度减少开发的工作量。
使用前提:Xcode 4.2以上 LLVM3.0以上 设置编译器ARC有效。
2、RC的内存管理和思考方式
C来上班需要使用电灯,需要使用电灯人数+1 需要使用电灯人数:3
B下班不需要使用电灯,需要使用电灯人数-1 需要使用电灯人数:2
A下班不需要使用电灯,需要使用电灯人数-1 需要使用电灯人数:1
C下班不需要使用电灯,需要使用电灯人数-1 需要使用电灯人数:0
没人需要使用电灯 ,电灯关闭
这样我们就实现了通过定义一个需要使用电灯人数的变量,来管理电灯的开关。
一个正确的RC思想应该是如下方式:
1、自己创建的对象自动持有,使用,使用完,自己取消持有
2、不是自己创建的对象,先持有,再使用,使用完,取消持有(不能释放)release/autorelease
3、对于局部的autorelease变量,可以不持有,不释放,仅使用
现在来看看第一句话
怎样才算自己创建的对象?
只要是调用以下的方法
alloc
new
copy
mutableCopy
所生成的对象,都被称为“自己创建的对象”
例如:
1、id obj = [[NSObject alloc]init];
2、id obj = [NSObject new];
3、id otherObj = [NSMutableArray new];
id obj = [other copy];
4、id otherObj = [NSMutableArray new];
id obj = [other mutableCopy];
通过release/autorelease方法可以对自己创建的对象,进行释放。
怎样才算非自己创建的对象
只要不满足上述的情况,通过函数返回的对象,或者通过函数参数传来的对象,都可以算非自己创建的对象
比如:id obj = [NSArray array];
或者 -(void)setObj:(id)obj
{
};
我们通常的使用方法
拿到对象先retain
[obj retain];
然后使用,使用完毕
[obj release]; 这里不应该是释放对象,应该是放弃持有,不管从思想上,还是从实际代码的运行效果上
但是对于
{
id obj = [NSArray array];
}
obj是一个通过autorelease返回的局部变量,也可以不进行持有和取消持有
但是在非ARC下,只要不是自己创建的对象,还是建议用第二种方式来处理,即先持有,在使用,最后取消持有
还有一种简单的思考方式
alloc/new/copy/mutable的次数 + retain的次数 = release次数+autorelease的次数
保证这样的公式,才能你的程序没有问题
3、release与autorelease
release是立即对对象的引用计数-1或者释放对象
而autorelease会将对象注册的autoreleasepool,当pool结束时,将对注册到pool里面的对象进行引用计数-1或者释放对象
我们如何知道哪些对象注册到了pool中呢?
自己写的代码自不必说,只要调用autorelease方法就会注册到pool中
对于系统类库的函数返回的对象,有这个规则
以new/alloc/copy/mutableCopy开头的方法返回的对象,都是非autorelease对象,不会注册到pool,你得到这个对象,就直接创建并持有
其他方法开头的都是autorelease对象,这些对象都会注册到pool中