2
- (void)showWeakValue
{
    NSString * __weak weakString = [[NSString alloc] initWithFormat:@"First Name: AA"];
    NSNumber * __weak weakNum = [[NSNumber alloc] initWithInt:10];
    NSLog(@"weakString =  %@", weakString);
    NSLog(@"weakNum  = %@",weakNum);
}

出力は

 weakString =  (null)
 weakNum  = 10

なぜweakNumはnullではないのですか? 他にweakNumへの強い参照がないため、割り当て後すぐに割り当てを解除する必要があります。右?

4

2 に答える 2

4

weakNum(予想どおり) すぐに割り当てが解除され、コードが未定義の動作を呼び出すか、NSNumberトリッキーな最適化を行って、常に値 10 を保持し、プログラムの存続期間を通じて生きているシングルトンが返されると思います。

編集:ああ、ハァッ、いいえ。を使用してポインター自体をログに記録しました

NSLog(@"weakNum pointer: %016llx", (uint64_t)weakNum);

そして得た

weakNum pointer: 000000000003e883

今、それは奇妙です。16 バイト アラインされていない構造体へのポインタですか? したがって、これはタグ付きポインタです。

ポインタ値を分析してみましょう!0 番目 (LSB) のビットが設定されています。これはクリアです。つまり、タグ付きポインターを示します。

最初のビットも設定されています。リンクの背後にある参照によると、これは整数のタグ付きオブジェクト クラスです。それは私たちの期待に一致します。それが 0 番目のニブルです。

次に、次の (最初の) ニブル、つまりビット 4...7 には、値 8 があり100ます0100 for 16-bit integers。1000 は 8 ビットには収まりませんが、16 ビットには収まります。

そして、次に何がありますか?3e8、これは 10 進数 1000 の 16 進数です。

したがって、これがタグ付きポインターであることを証明しました。少なくとも、これをテストしたシステム (OS X 10.7.5 64 ビット) ではそうです。

于 2013-07-12T13:15:53.890 に答える