实际上内存管理的本质在ARC中并没有进行改变,都是“引用计数式内存管理”。ARC只是自动地帮助我们处理“引用计数”的相关部分。
引用计数式内存管理的思考方式:
自己生成的对象,自己持有
非自己生成的对象,自己也能持有
不再需要自己持有的对象时释放
非自己持有的对象无法释放
在每个编译单位上,都可以设置ARC的有效或无效。比如说每个文件都可选使用或不使用ARC。Xcode4.2版本之后默认设定为对所有文件ARC有效。
在ARC有效时,id类型和对象类型上必须附加有权修饰符。共有4种。
_ _strong _ _weak _ _unsafe_unretain _ _autoreleasing
_ _strong修饰符是id类型和对象类型默认的所有权修饰符。
附有_ _strong修饰符的变量在超出其变量作用域时,即在该变量被废弃时,会释放其被赋予的对象。
如“_ _strong”名称所示,该修饰符表示对对象的“强引用”。持有强引用的变量在超出其作用域时被废弃,随着强引用的失效,引用对象会随之释放。
上面的规则“自己生成的对象,自己持有”和“非自己生成的对象,自己也能持有”这两条,只需要通过对带_ _strong修饰符的变量赋值便可打成。通过废弃带_ _strong修饰符的变量(变量作用域结束或是成员变量所属对象废弃)或者对变量赋其他的值,都可以做到“不再需要自己持有对象时释放”。“非自己持有的对象无法释放”,由于不比再加入release,所以原本就不会执行。这些都是满足“引用计数式内存管理”的思考方式。
带有_ _strong修饰符的成员变量在持有对象时,容易发生循环引用。循环引用容易发生内存泄露。所谓内存泄露就是应当废弃的对象在超出其生存周期后继续存在。
_ _weak修饰符与_ _strong修饰符相反,提供弱引用。弱引用不能持有对象。
id _ _weak obj = [[NSObject alloc]init];
这段代码将自己生成并持有对象赋值给附有_ _weak修饰符的变量obj。即变量obj持有对象的弱引用。这样一来,为了不以自己持有的状态来保存自己生成并持有的对象,生成对象时就会被立即释放。
编译器会发出警告!
正确的方式是:
id _ _strong obj0 = [[NSObject alloc]init];
id _ _weak obj1 = obj0;
由于_ _weak并不能持有对象,这样就可以避免产生循环引用。它还有个优点。在持有某对象的弱引用时,如果该对象被废弃,则此弱引用将自动失效处于nil被赋值状态。
_ _weak用于iOS5以上的系统中,在iOS4中,则是使用_ _unsafe_unretained修饰符来代替。