コンパイラは賢く、すべてが同じ値を保持する多数の異なる NSString インスタンスを作成する代わりに、解放できない 1 つのインスタンスを作成し、他のすべてのインスタンスはプログラムでハードコードされた NSString を指すだけです。
また、ハードコードされた NSString の割り当てが解除されることはないため、自動解放プールによって割り当てが解除された後でも使用できます。
これは、間違ったメモリ管理をカバーするだけです。そして、あなたは絶対にこの振る舞いに頼るべきではありません.
編集。これ以上言うことはありません。stringWithString:literal で作成した NSString は、単にメモリ内のリテラルの場所を指します。
ちょっとした例:
NSString *string = @"Foo";
NSLog(@"%@ - %p", string, string);
NSString *string2 = string;
NSLog(@"%@ - %p", string2, string2);
NSString *string3 = [string copy];
NSLog(@"%@ - %p", string3, string3);
NSString *string4 = [string retain];
NSLog(@"%@ - %p", string4, string4);
NSString *string5 = [NSString stringWithString:string];
NSLog(@"%@ - %p", string5, string5);
NSString *string6 = [[NSString alloc] initWithString:string];
NSLog(@"%@ - %p", string6, string6);
それらはすべて同じアドレスを指していることがわかります。
2011-02-22 13:24:41.202 xxx[40783:207] Foo - 0x74120
2011-02-22 13:24:41.204 xxx[40783:207] Foo - 0x74120
2011-02-22 13:24:41.204 xxx[40783:207] Foo - 0x74120
2011-02-22 13:24:41.206 xxx[40783:207] Foo - 0x74120
2011-02-22 13:24:41.206 xxx[40783:207] Foo - 0x74120
2011-02-22 13:24:41.207 xxx[40783:207] Foo - 0x74120
そして、それらすべてが割り当て解除されることはありません。したがって、コード内の他のメソッドから string5 にアクセスすることができ、それは依然としてアドレス 295740 を指し、NSString "Foo" は依然として存在します。
ただし、文字列リテラルを指していない NSString オブジェクトはこの時点で割り当て解除され、不正なアクセス例外が発生します。
メモリ管理規則に違反していますが、文字列リテラルのみを使用している場合は気付かないでしょう。コンパイラの動作が変わるまで。
したがって、正しく行い、適切なメモリ管理を学び、内部に依存しないでください。後で必要になった場合に備えて、自動解放されたすべてのオブジェクトを保持します。文字列リテラルを指している場合でも