2016-12-06 14 views
3
id __weak obj1 = obj0; 

は、iOSとOSXためProのマルチスレッドとメモリ管理では__weakオブジェクトが自動解放プールに追加されるのはなぜですか?

id __weak obj1 = obj0; 
id __autoreleasing tmp = obj0; 

に等しいです。

しかし、なぜobj1が自動解放プールに追加する必要があるのか​​、オブジェクトの弱いポインタを作成してその寿命に影響を与えてはいけないと思います。

答えて

4
{ 
    NSObject* sp = [NSObject new]; 
    NSObject* __weak wp = sp; 
} 

上記コードが変換される。

id sp = objc_msgSend(NSObject, "new"); 
id wp; 
objc_initWeak(&wp, sp); 
objc_destroyWeak(&wp); 
objc_storeStrong(&sp, 0); 

1)obj_initWeakは、単に確実にするために強いポインタspで弱いポインタwpを関連付けることspが指し示すオブジェクトがdeallocedさwpだろうオートリセットnilにすると、指し示したオブジェクトの保持カウントを中断しません。
2)obj_destroyWeak弱ポインタ​​と強ポインタの関連付けを破棄します。
3)最後のステートメントのobj_storeStrong[sp release]に等しくなります。

しかし、ウィークポインタを使用すると、コンパイラはポイントされたオブジェクトの新しい参照を生成します。

{ 
    NSObject* sp = [NSObject new]; 
    NSObject* __weak wp = sp; 
    NSLog(@"%@", wp); 
} 

id sp = objc_msgSend(NSObject, "new"); 
id wp; 
objc_initWeak(&wp, sp); 
id tmp = objc_loadWeakRetained(wp); 
NSLog(@"%@", wp); 
objc_release(tmp); 
objc_destroyWeak(&wp); 
objc_storeStrong(&sp, 0); 

objc_loadWeakRetainedtmpNSLog声明の中で生きていることを確認するために参照カウントをインクリメントうになります。 objc_releaseオブジェクトを元の状態にリセットします。

結論として、__weakのこのデザインは、ウィークポインタの使用中に、その状態が一貫していることを保証します。 __weakの新しいimplmenetationはApple LLVM version 8.0.0 (clang-800.0.42.1)にリリースをautoreleasepoolに返信せず、objc_releaseを直接使用します。

関連する問題