obj-c NSString и alloc / retain / release - PullRequest
1 голос
/ 22 июля 2010

Вероятно, это вопрос, который больше относится к объекту alloc / retain / release, но я буду использовать NSString в качестве примера.Я знаю, что могу сделать:

NSString* myString = [[NSString alloc] initWithString:@"Test"];

, чтобы по существу выделить и инициализировать строку, на которую ссылается моя переменная myString, которую я должен позже вызвать [myString release].Однако, если после того, как я это сделаю, я установлю его на другую строку, такую ​​как:

myString = someOtherString;

, которая по существу создает утечку памяти, потому что я переназначил свой указатель на другой объект и потерял все ссылки наоригинальный, который я выделил?

Если я просто хочу лично выделить и освободить строку, а затем изменить ее значение в разное время, должен ли я использовать другой синтаксис, отличный от '=', или он перегружен для правильного изменениясодержимое объекта, который изначально представлен myString при использовании =.

Ответы [ 3 ]

4 голосов
/ 22 июля 2010

Да, в вашем примере вы теряете память.

NSString* myString = [[NSString alloc] initWithString:@"Test"];
myString = someOtherString;

Вы это должны сделать так:

NSString* myString = [[NSString alloc] initWithString:@"Test"];
[myString release];
myString = someOtherString;

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

1 голос
/ 22 июля 2010

Если вы передали право владения должным образом до назначения ему другого значения указателя, утечки не будет:

NSString *a = [[NSString alloc] init];
// ... 
[a release]; // relinquish ownership
a = someOtherString; // fine, we don't own the previous instance anymore

В тот момент, когда вы отказываетесь от владения объектом, вызывая release, вы должны считать его фактически освобожденным - это могло быть последней ссылкой на него. То, что указатель все еще имеет то же значение, является лишь побочным эффектом реализации и использования типов классов Objective-C.

В зависимости от ограничений памяти и того, что делает ваш код, вы также можете использовать autorelease d экземпляров:

NSString *a = [NSString stringWithString:@"moo"];
a = someOtherString; // fine, a will be released later by the nearest autorelease pool

Обратите внимание: если ссылка не локальная переменная, а ivar, вы, вероятно, захотите использовать объявленные свойства .

0 голосов
/ 23 июля 2010

Вы можете сделать следующее:

NSString *myString = [NSString stringWithString:@"Test"];

Возвращенная строка автоматически выпущена, поэтому вам не нужно ее освобождать.Вы также не "владеете" этим.Если это проблема, сделайте так, как предлагали другие, и отправьте сообщение release на myString, прежде чем переназначить его значение.

...