xcode4.2之前,object-c采用手动方式来管理内存,对象使用完之后不会自动销毁,需要显式地调用dealloc来释放控件,否则会发生内存泄漏,但是这其中会碰到无效指针的问题,如下:
NSString *str1 = [NSString stringWithFormat:@"1234567890"];
NSString *str2 = str1;
[str1 dealloc];
[str2 dealloc];
由于str1和str2指向同一对象,[str1 dealloc];已经销毁了这个对象,因此str2实际上变成了一个无效指针。再次调用dealloc会产生如下错误:
“pointer being freed was not allocated”
为了避免无效指针,object-c采用了引用计数的机制(ref count或者retain count),每个对象内部都保存一个数字,表示该对象被引用的次数。销毁对象的时候,不直接调用dealloc,而是调用release。release首先会将ref count减1,然后当ref count为0时,再调用dealloc销毁该对象。如下所示:
NSString *str1 = [NSString stringWithFormat:@"1234567890"];
NSString *str2 = str1;
//Objective-C指针赋值时,ref count不会自动增加,需要手动retain
[str2 retain];//Increments the receiver’s reference count. (required)
[str1 release];
[str2 release];
object-c还引入了autorelease pool的概念,在遵守一定规则的情况下可以实现内存的自动释放。
pool中的对象只有在该pool销毁时才被释放,例如:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int i, j;
for (i = 0; i < 100; i++ )
{
for (j = 0; j < 100000; j++ )
[NSString stringWithFormat:@"1234567890"];//产生的对象是autorelease的。
}
[pool release];//执行该语句之后,程序占用的内存逐步得到释放
xcode4.2之后,object-c引入了automatic reference counting(ARC)的内存管理机制,官方文档中这样描述:
“Automatic Reference Counting (ARC) is a compiler-level feature that simplifies the process of managing object lifetimes (memory management) in Cocoa applications.”
ARC默认是开启的,如下所示:
在ARC模式下编写如下的代码:
NSObject *obj = [[NSObject alloc] init];
// do some stuff
ARC的预编译阶段会自动将其转化为:
NSObject *obj = [[NSObject alloc] init];
// do some stuff
[obj release]; // **Added by ARC**