我在 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
我填了一个rdar://10636309, Associated objects leaking if NSZombie objects enabled in ARC-enabled project
最佳答案
我发现了问题的根源 - 我在出现此错误的两个项目中都启用了 NSZombie
对象。
据我所知,当启用僵尸对象时,正常实例在释放时被 NSZombie
替换,但所有关联的对象都保持事件状态!小心这种行为!
我创建了一个 rdar://10636309
更新:有一个workaround由 Cédric Luthi 提出,这个问题似乎已在 iOS 6 中得到修复。
关于Objective-C 关联对象在 ARC 下泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8710263/