2016-06-22 6 views
1

У меня есть следующий код. Когда я печатаю aString, это Прощай, и когда я печатаю bString, это Hellworld. Не следует, чтобы bString указывал на тот же объект, что и aString. Я ожидал, что и печатать До свидания. Также, когда я печатаю адреса памяти указателей, они представляют собой разные адреса памяти. Может кто-нибудь объяснить, почему?Указатели на тот же объект Objective-c

NSString *aString = @"Helloworld"; 
NSString *bString = aString; 

aString = @"Goodbye"; 

Я хочу, чтобы bString указывала на тот же объект, что и aString. Поэтому, если значение aString изменяется, значение bString также изменяется и наоборот. Как я могу это достичь?

+0

Почему вы ожидаете, что bString будет иметь последнее значение Astring? aString не является методом возврата его последнего значения. –

+0

Я хочу, чтобы bString указывала на тот же объект, что и aString. Когда я пишу NSString * bString = aString; не должно ли bString указывать на один и тот же объект в памяти? – James

+0

Это происходит в этот момент. –

ответ

4

Вот визуализация того, что происходит в вашем коде, построчно.

aString –––––––––> @"Helloworld" 

aString –––––––––> @"Helloworld" 
         ^
         | 
bString ––––––––––––––––– 

aString –––––––––> @"Goodbye" @"Helloworld" 
            ^
            | 
bString –––––––––––––––––––––––––––––– 

Как вы можете видеть, указывая aString на другой объект не имеет никакого влияния на объект, который bString уже указывает на. Вы просто получаете два указателя, каждый из которых указывает на разные объекты.

Для того, чтобы достичь желаемого поведения, имеющих aString и bString указывая на тот же объект, который вы должны быть в состоянии изменить, вы будете нуждаться в изменяемый объект (например, NSMutableString, как говорит Франклин).

Это позволит вам мутировать базовый объект, а не создавать и указывать на новый объект, поэтомуи bString будут оставаться на одном объекте после мутации, что позволяет им наблюдать одно и то же значение.

Мутация просто выглядеть следующим образом:

aString –––––––––> @"Helloworld" 
         ^
         | 
bString ––––––––––––––––– 

aString –––––––––> @"Goodbye" 
         ^
         | 
bString ––––––––––––––––– 
+0

Нужно ли использовать KVO для получения bString, измененного на основе aString? –

+1

@TejaNandamuri Если 'aString' является свойством, то да, вы действительно можете использовать KVO, чтобы наблюдать, когда изменяется его значение, или просто переопределите его сеттер, если вы делаете это изнутри самого класса. – Hamish

+1

Хороший приятель графа. Легче понять, чем адресный материал. –

3

После

NSString *aString = @"Helloworld"; 

в памяти 0x01 (или где-то) есть строка @"Helloworld"; то адрес 0x01 присваивается aString. После

NSString *bString = aString; 

по адресу 0x01 присваивается bString. Предупреждение! После

aString = @"Goodbye"; 

по адресу 0x01 является еще@"Helloworld"! Эта строка не изменить строку. Он создает новую строку @"Goodbye" и сохраняет ее на 0x46 (или где-то кроме 0x01) и назначает адрес 0x46 - aString. Чтобы сделать то, что вы хотите, попробуйте NSMutableString.

Примечание: не следует создавать новые NSMutableString s; изменить текущий с помощью

- (void)setString:(NSString *)aString 
0

1) Всякий раз, когда вы создаете строку, используя синтаксис @"", структура будет автоматически кэшировать строку. NSString - это особый класс, но структура позаботится об этом. Когда вы используете @"Some String" в нескольких местах вашего приложения, все они укажут на тот же адрес в памяти. Только когда вы используете что-то вроде -initWithData:encoding, строка не будет кэшироваться.

2) Другие ответы предложили вместо этого использовать -copy, но -copy будет создавать только неизменяемые копии, если приемник изменен. (Как NSMutableString) Когда вы отправляете -copy на неизменяемый объект, это будет то же самое, что и -retain.

NSString *originalString = @"Some String"; 
NSString *copy = [originalString copy]; 
NSString *mutableCopy = [originalString mutableCopy]; 
NSString *mutableCopyCopy = [mutableCopy copy]; 
NSString *anotherString = [[NSString alloc] initWithString:originalString]; 

originalString, копировать, mutableCopyCopy и anotherString будет все это указывает на тот же адрес памяти, только mutableCopy точки сделать другую область памяти.

+0

Под «фреймворком» вы подразумеваете «компилятор» и «кэшируете» вы имеете в виду [string interning] (https://en.wikipedia.org/wiki/String_interning). – Droppy