iOS内存管理机制的原理是引用计数,简单来说就是统计一块内存的所有权。当有一个对象或指针指向一块内存时,该内存的引用计数就加1(刚被创建出来时是0);如果之后该对象或指针不再指向该内存时,其引用计数就减1。当一块内存的引用计数为0时,系统便会立刻释放掉这块内存。
在开发时引用计数又分为ARC(Automatic Reference Counting)和MRC(Manual Reference Counting)。因为ARC是由系统来管理内存,所以不一定能够及时释放,这样有可能导致程序占用内存较大。若能够熟练使用MRC,则可以保证程序长时间运行在良好状态上。
在MRC中会引起引用计数变化的关键字有:alloc
、retain
、copy
、release
、autorelease
。(strong
关键字只用于ARC,作用等于retain
)
alloc
开辟一块新的内存空间,并使这块内存的引用计数从0增加到1,只能由类调用
retain
使对象的内存的引用计数加1,只能由对象调用
copy
复制一个对象到新的内存空间上,旧内存空间的引用计数不会变化,新的内存空间的引用计数从0增加到1,只能由对象调用。copy又分为浅拷贝和深拷贝
浅拷贝:只是拷贝地址与retain
等同
深拷贝:拷贝内容,会新开辟内存空间。对于容器类来说,深拷贝不会拷贝容器内元素的内容,只是进行了retain
或浅拷贝
release
使对象的内存空间的引用计数减1。如果引用计数为0的情况下再调用release
,会造成过度释放使内存崩溃。只能由对象调用
autorelease
与release
类似,但不是立刻减1。autorelease
会在程序走出自动释放池时执行release
,如:
@autoreleasepool {
obj = [[NSObject alloc] init];
[obj autorelease];
} //当程序走出“}”时,obj的引用计数就会减1
应注意:当一个对象的引用计数变为0占用内存被释放时,会调用-(void)dealloc
方法,所以如果在MRC下自定义类,必须在该方法里将该类中属性关键字设置为retain
或copy
的属性release
一次,以免造成内存泄露,重写方法不要忘记在第一行添加[super dealloc];
。
网友评论