NSString immutable позволяет менять его значения? - PullRequest
5 голосов
/ 26 ноября 2009

Код ниже компилируется и запускается, НО в соответствии со всеми книгами по разработке для iPhone и документацией Apple, это не должно! Может кто-нибудь объяснить мне, почему неизменный NSString позволяет изменять свои значения после того, как он был установлен? Я думал, что я должен использовать NSMuttableString, чтобы изменить контекст той же строковой переменной? Я использую SDK 3.1.

NSString *test =[[NSString alloc] initWithString:@"TEST"];
[test release];
test = @"TEST2";

Ответы [ 3 ]

21 голосов
/ 27 ноября 2009

Возможно, следующий пример добавит ответы Марка и Нильса и поможет прояснить ситуацию.

Неизменяемые струны

// Setup two variables to point to the same string
NSString * str1 = @"Hello World";
NSString * str2 = str1;

// "Replace" the second string
str2 = @"Hello ikilimnik";

// And list their current values
NSLog(@"str1 = %@, str2 = %@", str1, str2);

Изменяемые строки

// Setup two variables to point to the same string
NSMutableString * str1 = [NSMutableString stringWithString:@"Hello World"];
NSMutableString * str2 = str1;

// "Replace" the second string
[str2 setString:@"Hello ikilimnik"];

// And list their current values
NSLog(@"str1 = %@, str2 = %@", str1, str2);

Обратите внимание, что при использовании неизменяемого класса NSString единственный способ «заменить» строку - создать новую строку и обновить переменную «str2», чтобы она указывала на нее. Это, однако, не влияет на то, на что указывает «str1», поэтому оно все равно будет ссылаться на исходную строку.

В примере NSMutableString мы не создаем вторую строку, а вместо этого изменяем (мутируем) содержимое существующей строки «Hello World». Поскольку обе переменные продолжают указывать на один и тот же строковый объект, они обе сообщают о новом значении в вызове NSLog.

Важно различать переменную-указатель и фактический объект, на который она указывает. Объект NSString является неизменным, но это не мешает вам изменять значение переменной, указывающей на строку.

Тип данных "NSString *" - это указатель на объект NSString, а не сам объект. Если вы установите точку останова в любом из операторов NSLog в отладчике XCode, вы можете проверить необработанное значение каждой переменной, чтобы прояснить это.

7 голосов
/ 26 ноября 2009

TEST и TEST2 - это две разные строки, на которые указывает указатель * test.

Вы не изменяете содержимое явно выделенного объекта NSString из первой строки кода, но указываете * test на другой объект.

7 голосов
/ 26 ноября 2009

Вы не изменяете строку, вы просто переназначаете переменную test, чтобы она указывала на другую строку. Исходная строка не была изменена.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...