4

次の 2 つのケースを考えてみましょう。

// case 1
NSObject *strongOne = [[NSObject alloc] init];
NSObject * __weak weakOne = strongOne;

if (weakOne) {
    NSLog(@"weakOne is not nil.");
} else {
    NSLog(@"weakOne is nil.");
}

strongOne = nil;

if (weakOne) {
    NSLog(@"weakOne is not nil.");
} else {
    NSLog(@"weakOne is nil.");
}

これを出力します:

weakOne is not nil.
weakOne is not nil.

// case 2
NSObject *strongOne = [[NSObject alloc] init];
NSObject * __weak weakOne = strongOne;

strongOne = nil;

if (weakOne) {
    NSLog(@"weakOne is not nil.");
} else {
    NSLog(@"weakOne is nil.");
}

これを出力します:

weakOne is nil.

私の知る限り、strongOneの割り当てが解除されると、同じオブジェクトへの弱い参照が に更新されnilます。

私の質問:なぜそれが でのみ発生するのcase 2ですか?

4

2 に答える 2

1

私が知る限り、strongOne の割り当てが解除されると、同じオブジェクトへの弱い参照は nil に更新されます。

それは正しい。strongOneただし、nil に設定したときにオブジェクトの割り当てを解除するのではなく、ポインターを変更するだけです。ARC はおそらくautoreleaseオブジェクトstrongOneポイントを呼び出すため、自動解放プールが空になるまで、オブジェクトは実際には割り当て解除されません。

ケース2でのみ発生するのはなぜですか?

その場合、 ARCが送信releaseするように見えるため、オブジェクトの割り当てが解除され、弱い参照がすぐに更新されます。

または、コンパイラはstrongOne、弱いポインターに割り当てることを除いて、nil に設定する前に使用しないことに気づき、最初からオブジェクトを割り当てないことを決定する可能性があります。そのコードをステップ実行して、strongOnenil 以外の値を取得するかどうかを確認します。

于 2013-08-05T21:52:47.673 に答える
1

これは、weakOne を使用した if ステートメントに入ると、自動解放プールの保持カウントがインクリメントされるためだと思います。したがって、自動解放プールが空になるまで、ウィーク ポインターはゼロになりません。

 // Try this
NSObject *strongOne = [[NSObject alloc] init];
NSObject * __weak weakOne = strongOne; //count 1
@autoreleasepool {

    if (weakOne) { 
        NSLog(@"weakOne is not nil."); //count 2
    } else {
        NSLog(@"weakOne is nil.");
    }

    strongOne = nil; // count 1

    if (weakOne) { 
        NSLog(@"weakOne is not nil.");
    } else {
        NSLog(@"weakOne is nil.");
    }

} // count 0, therefore the weakOne become nil

if (weakOne) {
    NSLog(@"weakOne is not nil.");
} else {
    NSLog(@"weakOne is nil.");
}
于 2013-08-05T21:57:49.443 に答える