Objective-C 关联对象在 ARC 下泄漏

标签 objective-c automatic-ref-counting objective-c-runtime

我在 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/

相关文章:

iphone - 什么是 objc_setAssociatedObject() 以及在什么情况下应该使用它?

ios - 将对象保存到Firebase

iphone - 自定义按钮显示在模拟器上,但不显示在iPhone设备中

ios - 屏幕左侧的 UIButton(在 iOS 7 导航滑动区域)未突出显示

ios - 将 iPad 中显示的两个 Controller 分开显示在同一屏幕中以在 iPhone 中使用

objective-c - 具有委托(delegate)引用的 ARC 项目编译失败

objective-c - 新 NSObject 的最佳实践是什么 - 分配/初始化或更改现有?

objective-c - 弱自引用的通用类型

swift - 通过 Swift 中的另一个类用对象的新值设置未确定的属性

rust - 编码 SIMD 类型和将它们用于 Objective-C 运行时的函数的正确方法是什么?