2013-05-15 14 views
13

私はOBJC_ASSOCIATION_ASSIGNが存在することを知っていますが、対象オブジェクトが解放されている場合は参照をゼロにしますか?それとも、その参照が不要になるか、あとでアクセスが悪くなるという昔のようなものでしょうか?弱参照でobjc_setAssociatedObjectを使用

+0

ええ、本当です。やってみます。 – ultramiraculous

答えて

1

試した後、答えはNOです。

私はiOSの6シミュレータの下に次のコードを実行しましたが、それはおそらく、ランタイムの前の繰り返しで同じ動作を持っているでしょう:

NSObject *test1 = [NSObject new]; 

NSObject __weak *test2 = test1; 

objc_setAssociatedObject(self, "test", test1, OBJC_ASSOCIATION_ASSIGN); 

test1 = nil; 

id test3 = objc_getAssociatedObject(self, "test"); 

最後に、TEST1とTEST2は皆無であり、TEST3があります以前にtest1に格納されたポインタtest3を使用すると、すでに割り当てが解除されているオブジェクトにアクセスしようとします。

+0

そこにタイプミス? "test1"は "test"と "test2"にどのような関係がありますか? – Jeff

0

この動作はドキュメントやヘッダーではわかりませんので、現在の動作が何であるかを識別できたとしても、実装する必要はありません。私はそれがではなく、ではないと思います。理由は次のとおりです。

一般に、-deallocの間に、iVarsで参照番号をnilにする必要はありません。オブジェクトが解放された場合、解放されたオブジェクトまたはそのiVarsへのそれ以上のアクセスは、それ自体ではプログラミングエラーであるため、iVarsがゼロにされたかどうかは関係ありません。実際には、ではなく、ではなく、-deallocの間に間違ったアクセスが行われることをお勧めします。詳細が明らかになり、バグが早く公開されています。

編集:ああ、私はあなたの質問を誤解していると思います。弱い参照をゼロにしたい関連するストレージはそれらをサポートしていないようです。 __weakとマークされた1つのivar /プロパティを持つ簡単なパススルークラスを作成し、同じような効果を得ることができます。小さなkludgeyが、それは動作するだろう。

+0

私が見ているケースでは、オブジェクトが割り当て解除された後にオブジェクトにアクセスしようとすると間違いではありません。デリゲートへの参照のような弱い参照がある場合、私はそれがメッセージするときにもう存在しないと予想しています。 – ultramiraculous

26

超々実証されているように、OBJC_ASSOCIATION_ASSIGNは弱参照をゼロにしないので、割り当て解除されたオブジェクトにアクセスする危険性があります。しかし、あなた自身を実装するのはかなり簡単です。あなただけの弱参照を持つオブジェクトをラップする単純なクラスが必要になります。

@interface WeakObjectContainer : NSObject 
@property (nonatomic, readonly, weak) id object; 
@end 

@implementation WeakObjectContainer 
- (instancetype) initWithObject:(id)object 
{ 
    if (!(self = [super init])) 
     return nil; 

    _object = object; 

    return self; 
} 
@end 

次にあなたがOBJC_ASSOCIATION_RETAIN(_NONATOMIC)としてWeakObjectContainerを関連付ける必要があります。

objc_setAssociatedObject(self, &MyKey, [[WeakObjectContainer alloc] initWithObject:object], OBJC_ASSOCIATION_RETAIN_NONATOMIC); 

とそれをアクセスするためにobjectプロパティを使用しますWeakObjectContainerに似

id object = [objc_getAssociatedObject(self, &MyKey) object]; 
+1

Hehe!本当にスマートなアプローチ。大好きです!私はそれを覚えておきます。 – MonsieurDart

+0

なぜNSValue :: valueWithNonretainedObjectを使用しないのですか? – AlexDenisov

+2

' - [NSValue nonretainedObjectValue]'は* weak *オブジェクトを返さないため、弱参照をゼロにしません。 – 0xced

4

つ以上のオプション:

をゼロに弱参照を取得するために
- (id)weakObject { 
    id (^block)() = objc_getAssociatedObject(self, @selector(weakObject)); 
    return (block ? block() : nil); 
} 

- (void)setWeakObject:(id)object { 
    id __weak weakObject = object; 
    id (^block)() = ^{ return weakObject; }; 
    objc_setAssociatedObject(self, @selector(weakObject), 
          block, OBJC_ASSOCIATION_COPY); 
} 
関連する問題