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

发布于 2024-12-25 03:05:26 字数 1262 浏览 3 评论 0原文

我在 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 deallocate" 消息仅打印一次。如果我取消注释 -dealloc 中的 objc_setAssociatedObject 行,第二个对象也会被释放。

Objective-C 参考指出关联对象在对象销毁时自动释放。是编译器/ARC/什么问题还是我遗漏了什么?

更新

如果您从全新的项目运行此示例代码,它实际上是有效的。但我有两个支持 ARC 的项目,但没有。我会做一些调查并提供更好的样本。

更新2

我已经填写了rdar://10636309,关联对象泄漏如果在启用 ARC 的项目中启用 NSZombie 对象

I have encountered with a strange objc_setAssociatedObject behavior under ARC. Consider the following code:

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);
}

I'm creating an instance of DeallocTester, then I set another DeallocTester as an associated object for it, then both of them go out of scope.

I expect the -dealloc of the first object to be called, then the associated object to be deallocated too, but I see the "DeallocTester deallocated" message printed only once. If I uncomment the objc_setAssociatedObject line in -dealloc, the second object gets deallocated too.

The Objective-C reference states that associated objects are deallocated automatically upon object destruction. Is it a compiler/ARC/whatever issue or am I missing something?

Update

This sample code is actually working if you run it from a brand-new project. But I have two ARC-enabled projects where it doesn't. I'll do some investigation and provide a better sample.

Update 2

I've filled a rdar://10636309, Associated objects leaking if NSZombie objects enabled in ARC-enabled project

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

唐婉 2025-01-01 03:05:26

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

据我了解,当启用僵尸对象时,正常实例在释放时会被替换为 NSZombie,但所有关联的对象都保持活动状态!小心这种行为!

我创建了一个rdar://10636309

更新: Cédric Luthi 提供了一个解决方法,这个问题似乎已得到解决在 iOS 6 中。

I've found a source of a problem - I had NSZombie objects enabled in both my projects where this bug appears.

As far as I understand, when zombie objects are enabled, the normal instances are replaced with NSZombie upon deallocation, but all the associated objects are left alive! Beware of that behavior!

I've created a rdar://10636309

Update: There's a workaround by Cédric Luthi, and this issue appears to be fixed in iOS 6.

分分钟 2025-01-01 03:05:26

您发布的代码与 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 的情况下进行编译吗?

The code you posted works exactly as advertised under ARC. I rewrote your dealloc implementation to help make things a little more obvious.

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

Here's the resulting log:

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>

Are you sure you're compiling with ARC enabled?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文