看了下官方文档的关于object c 的内存管理,总结下:
在iphone中object c 中的内存管理是通过计数器来管理的,每个对象内部都有一个计数器.新建一个对象,或者这个对象被其他对象引用,多会使计数器加1.Retain 增加计数器值release 减少计数器值.当计数器为0时对象就dealloc自己.
在object c中你生成的一个对象那么你就有责任去释放它,内存管理的一般规则:
-
You own any object you create by allocating memory for it or copying it.
Related methods:alloc,allocWithZone:,copy,copyWithZone:,mutableCopy,mutableCopyWithZone:
-
If you are not the creator of an
object, but want to ensure it stays in memory for you to use, you can
express an ownership interest in it.
Related method:retain
-
If you own an object, either by
creating it or expressing an ownership interest, you are responsible for
releasing it when you no longer need it.
Related methods:release,autorelease
-
Conversely, if you are not the creator of an object and have not expressed an ownership interest, you mustnotrelease it.
考虑下面这个例子:
Thingamajig *thingamajig = [[Thingamajig alloc] init];
NSArray *sprockets = [thingamajig sprockets];
[thingamajig release];
thingamajig 需要release,因为很显然这里我们是thingamajig的owner。(第一条规则)
那么sprockets为什么不需要release呢。
首先我们不是sprockets的 creater.(第一条规则),我们也没有expressing an ownership interest,因为我们没有
retain它,(第二条规则) 所以我们不负责release它。
具体来看thingamajig的sprockets方法的实现:
(NSArray *)sprockets {
NSArray *array;
array = [[NSArray alloc] initWithObjects:mainSprocket,auxiliarySprocket, nil];
return [array autorelease];
}
可见分配的内存在方法里就已经用autorelease释放了,只不过是稍后释放。参见autorelease pool。
这里有个很重要的原则:
Becausethe classcreates the new object,itis responsible for disposing of the new object.
这个对象在哪里生成的,就应该在哪里释放。
所以你看到很多类有以自己类名为方法的构造函数,你调用的时候就不需要release.因为在这个构造函数中已经做
过autorelease了。
你没有alloc这个对象就不负责release它
现在来看规则2,有些时候我们在自己的类里要引用其他的对象,如把这个其他的对象变成自己的成员变量。
那么就有一个问题,这个被引用的对象是否被release不被你控制,一旦它被release,你自己的程序就会出问题
这时候我们就需要retain这个对象。表示你这个类也拥有这个对象,只有你自己的类release后,被引用的对象才有可能被release
一般的set 方法:
@interface Counter : NSObject {
NSNumber *count;
}
- (void)setCount:(NSNumber *)newCount {
[newCount retain];
[count release];
count = newCount;
}
在set中我们对传进来的对象进行了retain. 为什么要先retain后release,因为如果newCount和count是同一个对象
先release的话会导致这个对象delloc.