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

use*_*375 4 cocoa objective-c

鉴于以下类别定义,无论是否使用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);
}
Run Code Online (Sandbox Code Playgroud)

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

rob*_*off 5

您无需执行任何特殊操作dealloc来"清理"关联对象.运行时会为您处理它.这与ARC无关.

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

UPDATE

回应您的评论:您正确的是,在释放主对象时,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.