4

次のカテゴリ定義を考えると、ARC を使用する場合と使用しない場合の両方で -dealloc を処理するにはどうすればよいでしょうか? 私は現在 ARC を使用しており、私の知る限り、Instruments をいじってみると、プロパティはクリーンアップされていますが、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);
}

これは私自身の啓蒙のためのものですが、解決策があまりにもハックでなければ、実際にこれを使用したい場所がいくつかあるかもしれません.

4

1 に答える 1

5

dealloc関連付けられたオブジェクトを「クリーンアップ」するために特別なことをする必要はありません。ランタイムがそれを処理します。これは ARC とは無関係です。

ARC を使用していない場合は、必ず[super dealloc]独自のdeallocオーバーライドを呼び出す必要があります。ただし、関連付けられたオブジェクトの使用に関係なく、これを行う必要があり、忘れるとコンパイラが警告します。

アップデート

あなたのコメントに応えて: あなたは、Objective-C ランタイム リファレンスが、メイン オブジェクトの割り当てが解除されたときに、関連付けられているオブジェクトが解放される (関連付けポリシーに基づいて適切な場合) と明示的に述べていないことは正しいです。しかし、それが唯一の妥当なアクションです。関連付けられたオブジェクトのポイントは、メイン オブジェクトのソース コードを変更せずにサブオブジェクトをメイン オブジェクトにアタッチすることだからです。

いずれにせよ、Objective-C ランタイムのソース コードはオープン ソースであるため、これが実際に実装されているものであることを確認するために調べることができます。

を見てNSObject.mmください。-[NSObject dealloc]_objc_rootDeallocobject_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

于 2013-03-07T16:52:07.113 に答える