#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:
Все, что вы сохраняете, вам нужно освободить. Вы не можете зависеть от того, когда авторелиз выпустит содержимое пула.
Этот вопрос задавался ранее. Вот простой ответ