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