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 deallocate"
消息仅打印一次。如果我取消注释 -dealloc
中的 objc_setAssociatedObject
行,第二个对象也会被释放。
Objective-C 参考指出关联对象在对象销毁时自动释放。是编译器/ARC/什么问题还是我遗漏了什么?
更新
如果您从全新的项目运行此示例代码,它实际上是有效的。但我有两个支持 ARC 的项目,但没有。我会做一些调查并提供更好的样本。
更新2
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我发现了问题的根源 - 我在出现此错误的两个项目中都启用了
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.
您发布的代码与 ARC 下宣传的完全一样。我重写了您的
dealloc
实现,以帮助使事情变得更加明显。以下是生成的日志:
您确定在启用 ARC 的情况下进行编译吗?
The code you posted works exactly as advertised under ARC. I rewrote your
dealloc
implementation to help make things a little more obvious.Here's the resulting log:
Are you sure you're compiling with ARC enabled?