Простое копирование указателей с Objective C - PullRequest
0 голосов
/ 06 февраля 2012

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

 NSString *string1=@"hello";
 NSString *string2=string1;
 string2=@"changed";
 NSLog(@"string1:%@, string2:%@", string1, string2); //"string1:hello, string2:changed"

Ответы [ 3 ]

4 голосов
/ 06 февраля 2012

Вам нужен указатель на экземпляр NSString. Пример:

NSString *string1 = @"Hello!";
NSString **string2 = &string1; // get the address of string1
*string2 = @"changed"; // set what string2 points to be 'changed'

NSLog(@"string1:%@, string2:%@", string1, *string2); // should print "string1: changed, string2: changed" 
3 голосов
/ 06 февраля 2012

Когда вы делаете второе присваивание вашей переменной string2, вы не изменяете содержимое того, к чему относится переменная в настоящее время, в этом случае то же самое NSString, что и переменная string1, а скорее ваше изменение к чему относится string2.

Картинка (код) стоит тысячи слов:

Каждый объект и переменная имеют внутреннее имя, обычно называемое адресом . Адреса обычно пишутся в виде шестнадцатеричных чисел, например, 0xdeadbeef, значение номера не важно для вас - это просто метка.

Когда вы пишете:

NSString *string1 = @"Hello!";

правая часть просит Objective-C создать NSString со значением @"Hello", в результате получается адрес, скажем 0xfeeddeaf. Сторона lhs запрашивает переменную, способную содержать в себе NSString * - ссылку на NSString; вызвать эту переменную string1; и сохранить результат rhs, 0xfeeddeaf, в него.

Когда вы сейчас пишете:

NSString *string2 = string1;

это приводит к переменной string2, также содержащей 0xfeeddeaf. Между содержимым string1 и string2 нет никакой связи, присваивание просто копирует значение (в данном случае это адрес).

Наконец, когда вы пишете:

string2 = @"changed";

это создает NSString со значением @"changed" с адресом, скажем, 0xbeedcafe и сохраняет его в string2. Итак, теперь string1 содержит 0xfeeddeaf, который является адресом @Hello, а string2 содержит 0xbeedcafe, который является адресом @"changed".

Я предполагаю, что когда вы пишете, что вы "пытаетесь изменить содержимое одного указателя с помощью другого", вы хотите, чтобы string1 и string2 ссылались на тот же объект, чье значение вы можете изменить. Вы не можете изменить значение NSString, они не изменяются (неизменяемые) после создания. Вместо этого вы должны использовать NSMutableString и , вам нужно использовать метод для изменения значения объекта NSMutableString - как показано выше, если вы используете присвоение, вы меняете, какой объект упоминается, а не содержимое объекта.

Предполагается, что вы используете ARC [*], а затем изменили код на:

NSMutableString *string1 = [NSMutableString stringWithString:@"Hello"];
NSMutableString *string2 = string1;
[string2 setString:@"changed"];

выполнит то, что, я думаю, вы намерены. Первые две строки выполняются аналогично приведенному выше, и в итоге вы получаете string1 и string2, содержащие один и тот же адрес. Третья строка изменяет адрес, на который они оба ссылаются - у вас есть связь, которую вы намеревались.

[*], если вы используете GC или retain / release, измените rhs первой строки на [[NSMutableString alloc] initWithString:"@Hello"]

0 голосов
/ 06 февраля 2012

В качестве альтернативы ответу Ричарда Дж. Росса III, поскольку они уже являются указателями - покупая вам уровень косвенности - просто убедитесь, что вы меняете то, на что они указывают по адресу, оставляя его по этому адресу. Так, например,

NSMutableString *string1 = [[NSMutableString alloc] initWithString:@"hello"];
NSMutableString *string2 = string1;

[string2 setString:@"changed"];

NSLog(@"string1: %@, string2: %@"); // "string1: changed, string2: changed"

Это на самом деле нереализуемое общее решение, потому что оно слишком сильно противоречит потоку обычных практик Какао, но понимание того, что происходит с указателями и как они передают объекты, стоит.

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