2010-07-22 1 views
1

Это, вероятно, вопрос, касающийся объекта alloc/keep/release, но я буду использовать NSString в качестве примера. Я знаю, что я могу сделать:obj-c NSString и alloc/retain/release

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

по существу выделить и инициализировать строку, на который ссылается моей переменной MyString, который я должен позже назвать [релиз туЗЬптда] на. Однако, если после того, как я делаю это, я поставил его в какой-то другой строки, такие как:

myString = someOtherString; 

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

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

ответ

4

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

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

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

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

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

+0

Правильно, и утечка памяти похожа на вашу собаку, идущую по клиентам, которая высыхает, когда слово обходит вас, и вы продолжаете терять собак. – jasongetsdown

+0

Я думаю, что ваша аналогия падает немного короче, потому что если «поводок» похож на счетчик ссылок, а собака «убегает», если у нее нет привязок к ее воротнику, тогда мой пример не так уж и будет поднимать поводок другой собаки так же, как отпускать мой поводок и поворачиваться, чтобы наблюдать за другой собакой. Похоже, что более правильная аналогия заключалась бы в том, чтобы не иметь владельцев, держащих поводки, так же как добавление поводок, который соединяется с фонарным столбом или удаляет их и т. Д. Но спасибо за это разъяснение. :) – Joey

+0

Sheesh, все критики ... Объяснение ACBurk было отличным (программисты!) – pchap10k

1

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

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 

Обратите внимание, что если ссылка не локальная переменная но Ивар, вы, вероятно, хотите вместо этого используйте declared properties.

0

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^