Objective-C相关的对象在ARC下泄漏



我在ARC下遇到了一个奇怪的objc_setAssociatedObject行为。考虑下面的代码:

static char ASSOC_KEY;
@interface DeallocTester : NSObject
@end
@implementation DeallocTester
- (void) dealloc
{
    NSLog(@"DeallocTester deallocated");
    //objc_setAssociatedObject(self, &ASSOC_KEY, nil, OBJC_ASSOCIATION_RETAIN);
}
@end
@implementation AppDelegate
- (void) applicationDidFinishLaunching:(UIApplication *)application
{
    NSObject *test = [[DeallocTester alloc] init];
    objc_setAssociatedObject(test, &ASSOC_KEY, [[DeallocTester alloc] init],
                             OBJC_ASSOCIATION_RETAIN);
}

我正在创建一个DeallocTester的实例,然后我将另一个DeallocTester设置为它的关联对象,然后它们都超出了作用域。

我期望第一个对象的-dealloc被调用,然后关联的对象也被释放,但是我看到"DeallocTester deallocated"消息只打印一次。如果我取消注释-dealloc中的objc_setAssociatedObject行,第二个对象也会被释放。

Objective-C引用声明关联的对象在对象销毁时自动释放。它是编译器/ARC/任何问题还是我错过了什么?

如果你在一个全新的项目中运行这个示例代码,它实际上是工作的。但我有两个支持arc的项目却没有。我会做些调查,提供一个更好的样本。

更新2

我已经填了一个雷达://10636309,如果NSZombie对象在ARC-enabled项目中启用,关联对象泄漏

我发现了一个问题的根源——我在出现这个错误的两个项目中都启用了NSZombie对象。

据我所知,当僵尸对象被启用时,正常的实例在释放时被NSZombie替换,但所有相关的对象都是活的!当心那种行为!

我已经创建了一个rdar://10636309

Update: csamdric Luthi有一个解决方案,这个问题似乎在iOS 6中得到了修复。

您发布的代码完全符合ARC下的广告。我重写了你的dealloc实现,以帮助使事情更明显。

- (void)dealloc
{
    NSLog(@"deallocating %@", self);
}

结果日志如下:

2012-01-03 06:49:39.754 ARC  Stuff[47819:10103] deallocating <DeallocTester: 0x6878800>
2012-01-03 06:49:39.756 ARC  Stuff[47819:10103] deallocating <DeallocTester: 0x688b630>

你确定你在编译时启用了ARC吗?

最新更新