在使用 ARC 并启用僵尸对象的项目中,如果一个对象在释放时持有对另一个对象的强引用,则该对象不会被释放。
这段代码演示了这个问题:
@interface TestInner : NSObject
@end
@implementation TestInner
- (id)init {
if ( (self = [super init]) ) {
}
NSLog(@"-[TestInner init]: %p", self);
return self;
}
- (void)dealloc {
NSLog(@"-[TestInner dealloc]: %p", self);
}
@end
@interface TestOuter : NSObject
@end
@implementation TestOuter {
TestInner * _inner;
}
- (id)init {
if ( (self = [super init]) ) {
_inner = [[TestInner alloc] init];
}
NSLog(@"-[TestOuter init]: %p", self);
return self;
}
- (void)dealloc {
NSLog(@"-[TestOuter dealloc]: %p", self);
// _inner will not release without this if zombies are enabled
//_inner = nil;
}
@end
分配和释放 TestOuter 实例会产生以下日志消息:
-[TestInner init]: 0x9d00f00
-[TestOuter init]: 0x9d00f30
-[TestOuter dealloc]: 0x9d00f30
TestInner 实例永远不会被释放。然而,关闭僵尸会导致 TestInner 实例被释放。
切换到 ARC 的好处之一是我们很少需要实现一个 dealloc 方法来简单地释放持有的对象引用。似乎启用了僵尸,这有助于在开发过程中捕捉各种错误,但这种好处无法实现。我仍然需要实现 dealloc 方法只是为了将我持有的引用设置为nil
.
我在这里遗漏了什么,或者这真的是 ARC 与僵尸混合时的预期行为吗?