作者yllan (蓝永伦)
看板MacDev
标题Re: [quiz] NSImage's leak
时间Wed Nov 28 17:20:04 2007
※ 引述《anpig (Andrew)》之铭言:
: 我想我大概大解了,不过还有一个问题,就是在accessor methods中放如上
: 的autorelease,那麽这个someMember object会被放到哪个autorelease pool呢?
: 是这个someMember所属的object中的autorelease pool还是receiver的?
: 如果是前者的话,是否表示这个someMember得等到其所属的object deallocate时
: 才会被release吗?
并非 someMember 所属 object 中的 autorelease pool 也非 receiver 的。
事实上一般来说,并不会有物件 "own" 某个 NSAutoreleasePool。
我说的 own 是指 instance variable 那样。
以下我写一个简单版的 NSAutoreleasePool 也许更能看出来:
@implementation NSAutoreleasePool
// 记录目前的 Autorelease Pool, 假设有这个 NXStack 这个 class 啦...
static NXStack *poolStack;
- (id) init {
if (poolStack == NULL) poolStack = new NXStack(); // Singleton
if (self = [super init]) {
// 唔,这个 hash 记录了被加到 pool 里的 object 一共被加了几次
// 同样还是假设有 C++ 的 class 可以用... 反正看得懂就好嘛
objectAutoreleaseCountHash = new NXHash(); // instance variable
poolStack->push(self); // global static
}
return self;
}
// 这就是我说的「最靠近」的意思
+ (NSAutoreleasePool *) topMostPool {
return poolStack->top();
}
- (id) addObject: (id) obj {
self->objectAutoreleaseCountHash[obj]++;
return obj;
}
- (void) dealloc {
// 连 ObjC 2.0 语法都跑出来了... 囧 同样也是看得懂就好
for (id key in self->objectAutoReleaseCountHash) {
for (int i = 0; i < objectAutoReleaseCountHash[key]; i++)
[key release];
}
poolStack->pop();
[super dealloc];
}
@end
然後一般的 autorelease 是这样实作的:
@implementation NSObject
- (id) autorelease {
return [[NSAutoreleasePool topMostPool] addObject: self];
}
@end
所以当你产生了一个新的 Pool,他会被推到某个 Stack 上,而收到
autorelease 的物件就会被这个 Stack 上最新产生的 Pool 所记录。
当 Pool 自己要被 deallocate 时,就把自己移出 Stack,并且把刚刚
记录的物件和次数给 release 回来,大致是这样。
所以这个问题的回答是,看当时哪一个 pool 是最近产生、又没有
dealloc'd ,就会被加到那个 pool。
: 突然想到,既然你说这个delay release会等到最靠近的autorelease pool
: release时,所以是否可以把autorelease pool当作对autoreleased object
: 强制release的一个机制?
: (当然如果被其他object retain住的不算)
?看不太懂这段...
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 59.112.163.47