如何释放在运行时添加到类别中的属性?

时间:2013-03-07 16:46:57

标签: objective-c cocoa

鉴于以下类别定义,无论是否使用ARC,我如何处理-dealloc?我目前正在使用ARC,据我所知,并且在仪器中进行探索,这些属性正在被清理,但我并不是100%有信心。

@interface NSObject (SuperUsefulThingIWishAllNSObjectsHad)
@property (nonatomic, copy) NSString *foo;
@end

#import <objc/runtime.h>
@implementation NSObject (SuperUsefulThingIWishAllNSObjectsHad)
static const void *MyPropertyKey = &MyPropertyKey;
@dynamic foo;
- (NSString *)foo
{
    return objc_getAssociatedObject(self,
                                    MyPropertyKey);
}

- (void)setFoo:(NSString *)foo
{
    objc_setAssociatedObject(self,
                             MyPropertyKey,
                             foo,
                             OBJC_ASSOCIATION_COPY);
}

这更适合我自己的启发,但如果解决方案不是 hacky,我可能会有一些地方我真的想要使用它。

1 个答案:

答案 0 :(得分:5)

您无需在dealloc中执行任何特殊操作即可“清理”关联对象。运行时会为您处理它。这与ARC无关。

如果您使用ARC,则需要确保在自己的[super dealloc]覆盖中调用dealloc。但无论您使用相关对象,都需要这样做,如果您忘记,编译器会发出警告。

更新

回应您的评论:您正确的是,在释放主对象时,Objective-C运行时参考未明确说明已释放关联对象(如果适用,基于关联策略)。但这是唯一合理的操作,因为关联对象的要点是将下级对象附加到主对象而不更改主对象的源代码

无论如何,Objective-C运行时的源代码是开源的,所以我们可以检查它以验证这确实是实现的。

查看NSObject.mm,您会看到-[NSObject dealloc]来电_objc_rootDealloc来调用object_dispose

object_dispose功能位于objc-runtime-new.mm,并调用objc_destructInstance,调用_object_remove_assocations

_object_remove_assocations函数(是的,它在源代码中有拼写错误)在objc-references.mm中。它会删除与要解除分配的对象关联的所有对象,并在适当时释放它们。如果您查看objc_removeAssociatedReferences,它是公共API的一部分,并在objc-runtime.m中定义,您会看到它也会调用_object_remove_assocations