2

可能重复:
为什么在使用 ARC + NSZombieEnabled 时对象未解除分配

在使用 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 与僵尸混合时的预期行为吗?

4

0 回答 0