iPhone: вопросы новичка в управлении памятью

#iphone #memory-management

#iPhone #управление памятью

Вопрос:

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

Я только что закончил свое первое приложение и начал тестировать его на предмет утечек. Их было много 🙂 Я изменил код, чтобы устранить утечки, а затем начал получать исключения BAD_ACCESS. Теперь к моим вопросам:

  • У меня есть объект UITextView, давайте назовем его «utv». Я увидел, что его поле «текст» определено следующим образом:

    @свойство (неатомное, копировать) NSString * текст;

Если я напишу следующую строку кода:

 utv.text = [NSString stringWithString:@"Blabla"];
  

Я не должен беспокоиться о пуле автоматического выпуска, освобождающем строку, верно? Потому что он использует copy?

  • Что, если бы это было определено как

    @свойство (неатомное, сохранить) NSString * текст;

    Должен ли я по-прежнему не беспокоиться о пуле автоматического освобождения, потому что сохранение увеличило количество ссылок на 1?

  • Могу ли я узнать, когда пул автоматического обновления выпустит строку, которую я создаю с помощью stringWithString вместо initWithString?

Спасибо! Илай

Комментарии:

1. Просто комментарий помимо основного вопроса. Сегодня я обнаружил видеосессию WWDC2010 311: Расширенный анализ памяти с помощью инструментов . Я также все еще новичок, и это дало мне много понимания того, как отслеживать утечки, заброшенную память и как справляться с предупреждениями о памяти.

Ответ №1:

На мой взгляд, вы в значительной степени ответили на свой собственный вопрос. Если свойство было retain единицей, новое значение будет отправлено retain сообщением в его синтезированном методе установки, так что вам не стоит беспокоиться об этом 🙂

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

 // assign 
property = newValue;

// retain
if (property != newValue) {
    [property release]; 
    property = [newValue retain];
}

// copy 
if (property != newValue) {
    [property release]; 
    property = [newValue copy];
}
  

Комментарии:

1. Спасибо за ответ. Я только что прочитал несколько связанных вопросов и увидел, что кто-то написал, что это obj = someValue отличается от self.obj = someValue . Почему это? Разве обе строки кода не вызывают установщик?

2. @Eli — нет, первый просто присваивает только объекту self.obj = someValue и будет вызывать свойство

Ответ №2:

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

Обе эти строки создают сохраненные свойства:

 @property (nonatomic, copy) NSString *text;
@property (nonatomic, retain) NSString *otherText;
  

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

 self.text = string1; // this retains a copy of string1
self.text = string2 // this releases the copy of string1 and retains the copy of string2
self.text = nil; // this releases the copy of string2
  

У вас есть self.text и self.otherText, поэтому вам нужно освободить их в dealloc.

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

Ответ №3:

Вы правы. Вы не должны беспокоиться о пуле автоматического освобождения, когда свойство установлено как сохранить или скопировать. Вы не будете знать, когда NSAutoreleasePool освободит вашу строку, но вы можете с уверенностью предположить, что сможете использовать ее в рамках того же метода, который объявлен свободно. Предполагается, что у каждого потока есть свой собственный NSAutoReleasePool который может быть отключен в любое время, но обычно отключается в начале каждого цикла выполнения.

Комментарии:

1. Вы не можете предположить, когда сработает автозапуск.

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

Ответ №4:

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

Этот вопрос задавался ранее. Вот простой ответ

http://cocoadevcentral.com/d/learn_objectivec/