2013-06-24 1 views
1

Есть много сообщений по одной теме, и это может быть глупый вопрос, но я не смог понять эту концепцию.Почему объекты, такие как NSString и NSNumber, не могут быть перезаписаны?

Я знаю проблемы, возникающие при назначении изменяемой строки неизменяемому, и почему я должен использовать копию, чтобы избежать этих проблем.

Что я действительно не понимаю: что именно означает, что NSString нельзя изменить?

Если я это сделать:

NSString *foo = @"Hello World!"; 
foo = @"Hello everybody!"; 

Я понимаю, что я не изменяя значение Foo, а скорее заменить старый экземпляр с новым. Но тогда, как определено, что я не могу переписать изменяемый объект?

UPDATE Я попытался запустить следующий код:

-(void)immutable 
{ 
    NSString *myString1 = @"Hello!"; 
    NSString *myString2 = myString1; 

    NSLog(@"myString1 address: %p", &myString1); //Prints 0xbfffdb30 
    NSLog(@"myString2 address: %p", &myString2); //Prints 0xbfffdb2c 

    myString2 = @"Good bye!"; 
    NSLog(@"myString2 address: %p", &myString2); //Prints 0xbfffdb2c 

    NSMutableString *myMutableString = [NSMutableString stringWithString:@"Hello"]; 
    NSString *myString3 = myMutableString; 

    NSLog(@"myMutableString address: %p", &myMutableString); //Prints 0xbfffdb28 
    NSLog(@"myString3 address: %p", &myString3); //Prints 0xbfffdb24 

    [myMutableString setString:@"Hello World"]; 
    NSLog(@"myString3: %@", myString3); //Prints Hello World 

    myString3 = myString1; 
    NSLog(@"myString3 address: %p", &myString3); //Prints 0xbfffdb24 

    [myMutableString setString:@"Nothing to do"]; 
    NSLog(@"myString3: %@", myString3); //Prints Hello! 
} 

Я не удивлен, что адрес myString1 и myString2 различны, так как являются неизменными объектами. Но даже после назначения другой строки myString2 она все равно указывает на тот же адрес, что и раньше. Разве это не должно измениться?

Но в случае myMutableString и myString3 у них все еще есть разные адреса, хотя любое изменение myMutableString будет отражено в myString3. После того, как я назначил myString1 для myString3, адрес myString3 указывает, что он не изменяется, но тогда он больше не связан с myMutableString, так как каждое изменение, которое я ему делаю, больше не будет отображаться в myString3. Что вызывает связь myString3 и myMutableString в первую очередь?

+0

'& myString' получает адрес локального указателя, а не адрес объекта. Установите точку останова в начале метода и просмотрите адреса объектов в области отладки. –

+0

Спасибо! Результаты испытаний были довольно запутаны, но теперь все ясно. –

ответ

2

Когда вы пишете foo = @"Hello World!";, Foo указывал на NSString объект, который имеет данные "Hello World!", скажем, что этот объект находится по адресу 10.

Когда вы пишете foo = @"Hello everybody!", foo теперь указывает на новый объект, который имеет данные "Hello everybody!", предположим, что этот объект находится по адресу 50. Первый объект вообще не был изменен, вы просто сделали foo точкой другого объекта на другом адресе.

Если эти строки были изменяемыми, вы могли бы изменить содержание,

NSMutableString *foo = @"Hello World!".mutableCopy; //LEt's say, it's @ adress 10 
[foo appendString:@"How is it going?"]; // IT's still @ adress 10, but with new content. 

Foo теперь указывает на объект по адресу 10, который имеет измененное содержание "Hello World!How is it going?".

В первом случае вы не можете изменить NSString, потому что он не дает вам никаких методов для изменения данных по этому адресу. Это неизменность. NSMutableString, с другой стороны, дает вам эту способность, используя методы, такие как appendString: и appendString:. Таким образом вы можете изменить содержимое объекта по тому же адресу, не создавая новый объект для внесения этих изменений.

+0

Отличный ответ, я сделал небольшие изменения. Как комментарий в целом, с точки зрения использования, 'NSMutableString' на самом деле не используется.Обычно мы делаем копию строки или добавляем ее. Объекты Mutable в основном используются для 'NSMutableArray' и' NSMutableDictionary' (есть другие, но это два наиболее распространенных), потому что вам, вероятно, понадобятся динамические массивы и словари довольно часто. Но если вы их используете, не забудьте иногда «копировать», если они являются частью вашего публичного API. Если вы не хотите, чтобы кто-то испортил изменяемые объекты, сделайте их неизменными. Или наоборот с 'mutableCopy'. – swiftcode

+0

Благодарим вас за ответ. Я обновляю вопрос с помощью некоторого кода, который я пробовал, но он не работал, как я ожидал после прочтения вашего ответа. –

+0

@DiegoArmandoRincon Оставьте комментарий. –