8

Iallocinit2 つのNSString変数のポインターを比較すると、それらは同じです。これを示すスニペットを次に示します。

NSString *s1 = [[NSString alloc] initWithString:@"hello world"];
NSString *s2 = [[NSString alloc] initWithString:@"hello world"];

if (s1 == s2) {
    NSLog(@"==");
}else {
    NSLog(@"!=");
}

s1s2が同じなのはなぜですか?

4

2 に答える 2

14

ここでは、次の 3 つのことが行われています。

まず、渡す 2 つの同一の文字列リテラルinitWithString:の開始アドレスは同じになります。これは、定数データの明らかな最適化です。

第 2 に、alloc と init を文字列でネストすると、ランタイムが最適化を実行し、alloc 呼び出しは基本的にノーオペレーションになります。これは、NSPlaceholderStringクラスを使用して行われます。initWithString:これは、ここで返されるポインタがallocからではなく から来ることを意味します。

3 番目に、ボンネットの下でinitWithString:を呼び出しCFStringCreateCopyています。これには、次のような動作があります。このルーチンは不変の文字列を作成するためのものであるため、最適化されています。渡されたものと同じオブジェクトを呼び出しCFRetain()て返すだけです。

非常に興味深い質問をありがとう。楽しく解いていました。

于 2012-07-23T05:20:19.220 に答える
0

@"hello world" 文字列はクラスNSConstantStringです。@"hello world" を 2 つの場所で使用すると、それらはまったく同じオブジェクトを参照することになります。

ドキュメントから。

ソース コードで文字列オブジェクトを作成する最も簡単な方法は、Objective-C の @"..." コンストラクトを使用することです。

NSString *temp = @"/tmp/scratch"; この方法で文字列定数を作成する場合は、UTF-8 文字を使用する必要があることに注意してください。このようなオブジェクトはコンパイル時に作成され、プログラムの実行中に存在します。コンパイラは、このようなオブジェクト定数をモジュールごとに一意にし、割り当てを解除することはありませんが、他のオブジェクトと同じように保持および解放できます。他の文字列と同じように、メッセージを文字列定数に直接送信することもできます。

BOOL same = [@"comparison" isEqualToString:myString];

于 2012-07-23T07:04:52.853 に答える