以下は、質問を確認するための私のコードです。
AとBの2つのクラスを作成します。
@interface A : NSObject
@property (strong, nonatomic) B *b;
@end
@implementation A
- (void)dealloc
{
[_b release];
[super dealloc];
}
@end
//
@interface B : NSObject
@property (nonatomic, strong) A *a;
@end
@implementation B
- (void)dealloc
{
[_a release];
[super dealloc];
}
@end
//そしてStrongViewController
、にはtempAとtempBがあり、どちらもプロパティを割り当てます。
@interface StrongViewController ()
@property (nonatomic, assign) A *tempA;
@property (nonatomic, assign) B *tempB;
@end
//ではviewDidLoad
、retain-cycleを作成し、aとbはお互いを保持します。
A *a = [[[A alloc] init] autorelease];
B *b = [[[B alloc] init] autorelease];
a.b = b;
b.a = a;
self.tempA = a;
self.tempB = b;
//次に、viewWillDisappear
で、保持サイクルを中断しようとします。
[super viewWillDisappear:animated];
self.tempA.b = nil; // Key line
//ここで、ステップバイステップでサイクルに飛び込みます。
AのdeallocとBのdeallocに2つのブレークポイントを設定しました。
//キーラインself.tempA.b = nil;
が実行されたとき:
//メッセージがAのbに送信dealloc
されたため、Bが呼び出さrelease
れましたsetB
:
// Bdealloc
では、release
メッセージがaに送信されたため、Adealloc
が呼び出されました。
//さて、_bはnil
デフォルトを使用しているためですsetB:
。
//しかし、setB:
以下のようなカスタムを使用するとどうなりますか?
//キーラインself.tempA.b = nil;
が実行されると、カスタムに遭遇しますsetB:
:
//これrelease
でbに送信されたので、Bに送信されますdealloc
:
// Bdealloc
では、[self holdCount]は0ではなく1のままであることに注意してください。なぜですか?
//ここでBでdealloc
、release
は_aに送信されたのでdealloc
、順番にAに送信され、そこで_bにrelease
送信されます。
// Here comes the difference, in A's dealloc, _b
is not nil, and _b's retainCount
is 1.
// According to my knowledge, if _b receives a release
message now, it will call its dealloc
then, because its retainCount is 1 for the moment.
// But, out of my imagination, it doesn't step into B's dealloc
recursively, but just step over to the next line, leaving the retainCount
with a big value 2147483648
:
// My question is on the above, why it step over when _b receives a release
message, instead of stepping into its dealloc
, while its retainCount
is still 1 ?
// And how the retainCount 2147483648
comes out?
//詳細には、NSObjectが「リリース」メッセージを実際に受信したときにどのように機能するか、誰もがソースコードを知っていますか?でもAさんにdealloc
、さんretainCount`はまだ1で、そうであるbが。
保持カウントが1のオブジェクトを解放すると、次のようになります。
オブジェクトは「デッド」としてマークされます。
Deallocメソッドが呼び出されます。
オブジェクトのメモリがOSに返されます。
オブジェクトがデッドとしてマークされている場合、保持と解放は効果がありません。ランタイムは、deallocを呼び出す前に、保持カウントをゼロに設定することすらしません。2番目のdeallocメソッドが呼び出され、retainCountが1を返しても、すでに死んでいるオブジェクトを解放しようとすると、何も起こりません。同じオブジェクトに対してdeallocが2回呼び出されることはありません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加