0

メソッド「retainCount」をテストすると、次のような質問がありました。

NSString *s_afmt0 = [[NSString alloc] initWithFormat:@""]; //-1
NSString *s_afmt1 = [[NSString alloc] initWithFormat:@"123"]; //1
NSLog(@"s_afmt0:%d", [s_afmt0 retainCount]);
NSLog(@"s_afmt1:%d", [s_afmt1 retainCount]);

result : s_autf0:-1 s_autf1:1 なぜだかわかりません。s_afmt0のretainCountが-1で、s_autf1のretainCountが1なのはなぜですか。@""と@"123"の違いは何ですか? 誰でも説明できますか?ありがとう

4

2 に答える 2

9

NSUInteger実際には符号なし整数 (形式指定子が%uではなくの型)である場合に、retainCount を符号付き整数として出力しています%d。-1 は と同等でUINT_MAX、オブジェクトに保持カウントがないことを意味します。NSString は、指定された文字列が不変であることを認識し、静的な @"" 空の NSString へのポインタをヒープに配置するのではなく割り当てた可能性があります。

実際、次のコードでこれを確認できます。

NSString* str1 = [[NSString alloc] initWithFormat:@""];
NSString* str2 = [[NSString alloc] initWithFormat:@""];

NSLog(@"string1: %p, string2: %p", str1, str2);

上記のコードは、str1 と str2 の両方に同じポインター アドレスを出力する必要があり、NSString がこの特定のケースを最適化するという私の理論を確認します。

06:46:30.142 StringTest[45214:303] string1: 0x7fff7d8acf90, string2: 0x7fff7d8acf90

それでは、これが NSString に固有のものかどうかを見てみましょう。そうでなければ、空の文字列に初期化されたすべての NSMutableString オブジェクトが同じメモリを指すことになります!

NSMutableString* str1 = [[NSMutableString alloc] initWithFormat:@""];
NSMutableString* str2 = [[NSMutableString alloc] initWithFormat:@""];

NSLog(@"string1: %p, string2: %p", str1, str2);

出力:

06:53:36.688 StringTest[45278:303] string1: 0x10010a850, string2: 0x10010a890

2 つの異なるメモリ ロケーション。これで、Foundation フレームワークの適切な小さな最適化が完了しました。ティル

編集:

bbum が指摘しているように、retainCount に依存するべきではありません。

于 2012-10-31T03:44:40.680 に答える
1

を使用するべきではありませんretainCountが、空の文字列@ ""は非常に一般的なリテラルであるため、コンパイラによって特別に扱われていることが原因である可能性があります。

また、なぜ文字列リテラルで文字列形式を使用しているのですか?これはテスト目的のためだけだと思いますが、次のものが必要です。

NSString *s_afmt0 = @""; // no need to use stringWithFormat here
于 2012-10-31T03:46:56.197 に答える