Object-c的内存管理是使用引用计数,来监测对象是否还在被使用,当不被使用的时候,释放内存。
关于引用计数retaincount,当使用alloc方法进行内存分配创建对象时,对象就有了一个引用计数,而且retaincount=1。之后,正在运行的应用程序可以在多个位置引用该对象,或者对象可能存储在一个数组中,也可能被其他位置的实例变量引用,只有在确定使用该对象的每个人都使用完后,才能释放它所占用的内存。每一次使用该对象,比如添加到数组中,使其引用计数加1;或者也可以手动保持该对象,就是自己调用ratain消息,[myObject retain]。不需要对象时,发动release消息,使对象引用计数减1。当对象的引用次数达到0时,系统指导不再需要这个对象(因为理论上它不再被引用),因此系统就会释放它的内存。
代码示例:
#import <Foundation/NSObject.h>
#import <Foundation/NSAutoreleasePool.h>
#import <Foundation/NSString.h>
#import <Foundation/NSArray.h>
#import <Foundation/NSValue.h>
Int main(int argc,char *argv[])
{
NSAutoreleasePool *pool=[[NSAutorelease alloc]init];
NSNumber *myInt=[NSNumber numberWithInteger:100];
NSNumber *myInt2;
NSMutableArray *myArr=[NSMutableArray array];
NSLog(@”myInt retain count=%lx”,(unsigned long)[myInt retainCount]);
//调用retainCount返回的是一个NSUInteger类型的无符号整数
[myArr addObject:myInt];
NSLog(@”after adding to array=%lx”,(unsigned long)[myInt retainCount]);
myInt2=myInt;
NSLog(@”after asssignment to myInt2=%lx”,(unsigned long)[myInt retainCount]);
[myInt retain];
NSLog(@”myInt after retain=%lx”,(unsigned long)[myInt retainCount]);
NSLog(@”myInt2 after retain=%lx”,(unsigned long)[myInt2 retainCount]);
[myInt release];
NSLog(@”after release=%lx”,(unsigned long)[myInt retainCount]);
[myArr removeObjectAtIndex:0];
NSLog(@”after removal from array=%lx”,(unsigned long)[myInt retainCount]);
[pool drain];
Return 0;
}
输出结果:
myInt retain count=1
after adding to array=2
after asssignment to myInt2=2
myInt after retain=3
myInt2 after retain=3
after release=2
after removal from array=1
检查addObject方法的文档,将发现,将对象添加到任何类型的集合都会使该对象的引用次数增加。这就意味着,如果随后释放了添加的添加对象,那么数组中仍然存在着该对象的有效引用,并且对象不会被释放。
代码中将myInt赋值给变量myInt2,要注意这个操作并没有使myInt对象的引用次数增加,这可能会在以后造成潜在的麻烦。例如如果对myInt的引用次数减少到0,并且它占用的空间被释放,那么myInt2将拥有无效的对象引用(将myInt赋值给myInt2的操作并没有复制实际的对象,只是指向myInt在内存中位置的指针)。因为多了一个队myInt对象的引用,为保持引用计数的同步,所以通过发送retain消息来同步引用计数。
所以,在示例中,一共有3次对myInt的引用,第一个是实际的对象本身,即创建对象,第二个是数组中的引用,第三个来自赋值引用。其中,添加对象到数组中会引起引用计数增加,但是赋值操作却不会。
整理摘自《objective-c 2.0程序设计》