看了下官方文档的关于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 must not release 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。
这里有个很重要的原则:
Because
the class
creates the new object,
it
is 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.