компилятор умен, и вместо того, чтобы создавать десятки разных экземпляров NSString, которые имеют одинаковое значение, он создает один экземпляр, который не может быть освобожден, а все остальные экземпляры просто указывают на NSString, жестко закодированную в вашей программе.
И так как жестко закодированный NSString никогда не освобождается, вы можете использовать его даже после того, как пул авто-выпусков освободил бы его.
Это просто покрывает ваше неправильное управление памятью. И вам определенно не следует полагаться на это поведение.
Edit. больше сказать нечего. NSString, созданный с помощью stringWithString: literal, будет просто указывать на расположение литерала в памяти.
Небольшой пример:
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, который не указывает на строковый литерал, будет освобожден в это время, и вы получите исключение неправильного доступа.
Вы нарушаете правила управления памятью, но никогда не заметите этого, если будете использовать только строковые литералы. Пока поведение компилятора не изменится.
Так что делай правильно, учись правильному управлению памятью и не полагайся на внутреннее устройство. Сохраните все свои автоматически выпущенные объекты, если они понадобятся вам позже. Даже если они указывают на строковые литералы