我在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吗?