Object-C的内存管理基于引用计数。如果要使用一个对象,并希望确保在使用期间对象不被释放,需要通过函数调用来取得“所有权”,使用结束后再调用函数释放“所有权”。“所有权”的获得和释放,对应引用计数的增加和减少。
所有权操作函数:
alloc 创建对象时调用,获得所有权
copy 拷贝对象时调用,获得所有权
retain 对象保持 获得所有权
release 释放所有权
autorelease 设置由系统自动释放所有权
NSArray, NSDictionary, NSSet等类在对象加入后计数加一获得所有权
注:对象由应用程序创建,但不是由应用程序释放,应用程序释放的只是其引用计数,当引用计数为0时由系统自动释放对象。可以在对象类中重写dealloc函数来扑获该动作。
应用举例:
NSString *str = [[NSString alloc] init]; //创建对象 获得所有权 引用计数为1
[str retain];//引用计数加1
[nsmutableArray addObject:str1];//引用计数加1
NSString *str2 = *str1;//引用计数不变
[str1 release];//引用计数减1
[NSMutableString stringWithString:@"test"];//引用计数加1,这是由于NSMutableString为可变字符串对象,而stringWithString:@"test"为常量字串不可改变,因此系统采用拷贝方式在存放该字符串
自动释放池
自动释放池主要对一些未采用引用计数的对象进行自动释放,如下:
NSString *string1 = [NSString stringWithString:@"test"];
NSString *string2 = @"test";
这些方式创建的对象均不采用引用计数机制,因此应用程序无法对它们进行释放,需要由系统来完成,这就需要采用自动释放池
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
...
[pool drain];
通常模块需要采用以上的内存函数对其内存进行管理,自动释放池也可以管理有引用计数的对象,但需要手动将对象舔加到自动释放池中,如下:
[str1 autorelease];//将str1放入到自动释放池,只将最近的对象引用存放到自动释放池了,如果同一个对象继续增加新的引用且希望放到自动释放池了必须重复运行该指令
该功能在子函数需要返回一个对象的情况很有用
由于autorelease效率不高,因此不建议所有的对象由autorelease进行管理,能通过release进行释放的尽可能采用release完成