objective-C不像C#、Java那样使用垃圾回收机制回收内存(GC),而是使用引用计数器机制管距内存。
引用计数器
引用计数器的原理:每个对象都有一个计数器,当对象创建或被引用时计数器加1,当引用取消时计数器减1,计数器为0时,系统自动销毁该对象。
内存释放原则
谁创建谁释放
属性与内存管理
使用@property关键字声明属性,实际上是让系统为这个属性合成getter和setter方法。
关于assign、retain和copy
assign用于基本数据类型,它合成的setter类似
-(void)setObjA:(ClassA *)a
{
objA = a;
}
retain
-(void)setObjA:(ClassA *)a
{
If(objA != a)
{
[objA release];
objA = a;
[objA retain]; //对象的retain count 加1
}
}
copy
-(void)setObjA:(ClassA *)a
{
ClassA * temp = objA;
objA = [a copyWithZone:nil];
[temp release];
}
自动释放池
自动内存释放使用@auyoreleasepool关键字声明一个代码块,当代码块执行完之后,在块中调用autorelease方法的对象都会自动调用一次release方法。这样就起到了自动释放的作用,同时对象销毁的过程也得到了延迟。
自动释放池实质是当自动释放池销毁后调用release方法,不一定能销毁对象。
由于自动释放池最后统一销毁对象,因此如果一个操作比较占用内存,最好不要放到自动释放池
注意事项
ARC虽然能够解决大部分的内存泄露问题,但是仍然有些地方是我们需要注意的。
循环引用两个对象互相强引用了对方,从而导致了谁也释放不了谁的内存泄漏问题。比如delegate对象需要设置weak,否则可能出现对象循环引用的问题。block如果使用了外部的局部变量或self,需要使用关键字weak。NSTime使用时也要注意,在dealloc前,调用invaildate方法。延时执行方法也是,父类销毁前先取消自身。