Использование памяти для удобства метода против метода init - PullRequest
4 голосов
/ 14 ноября 2008

Недавно, когда я посмотрел на управление памятью iPhone, я попытался сравнить удобный метод и метод init для одного и того же объекта. Например, у меня есть UIImageView, где он отображает загруженные NSData:

Метод удобства:

imageView.image = [UIImage imageWithData:[downloads dataAtIndex:0]];

метод инициализации:

UIImage *aImage = [[UIImage alloc] initWithData:[downloads dataAtIndex:0]];
imageView.image = aImage;
[aImage release];

Когда я пытаюсь переключаться между представлениями, чтобы увеличить использование памяти, и нажимаю «Предупреждение о симуляции памяти», использование памяти приложением увеличивается с 20 до 18 МБ, а метод init - с 20 до 13 МБ немедленно.

Я также ждал и взаимодействовал с приложением, чтобы дать время на выпуск авто-релиза удобного метода. Но это не сильно упало.

Что кроме различий между выпуском и выпуском, что еще способствовало разнице?

Ответы [ 4 ]

4 голосов
/ 14 ноября 2008

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

1 голос
/ 14 мая 2009

Что я заметил, так это то, что с автоматически высвобождаемыми объектами, под давлением памяти, существует системный ГХ, который происходит с заметным падением производительности, если вы не освобождаете свои пулы своевременно.

Кроме того, использование метода init / release позволяет потреблению памяти в циклах оставаться постоянным, в то время как использование пула автоматического выпуска создает пики. В некоторых случаях, когда возникают проблемы с памятью, быстрое увеличение объектов в пуле автоматического выпуска может привести к загрузке приложения до того, как система предпримет шаги по очистке таких элементов, как открытые электронные письма, вкладки мобильного сафари и запущенные элементы iTunes.

Суть в том, что я склонен чаще использовать init, потому что это делает потребление памяти моим приложением более стабильным, и я вижу меньше проблем с случайной загрузкой. Постепенное увеличение потребления памяти позволяет демонам очистить систему, не убивая мое приложение. Наконец, если вы используете ключевое слово @property в своих классах, вы должны быть осторожны с такими вещами, как:

myProperty = [NSMutableArray arrayWithCapacity:10];

Поскольку произойдет, когда пул в вашем классе main.m будет собран, этот элемент исчезнет, ​​что приведет к падению из-за вызова метода для освобожденного объекта. Если вы устанавливаете его с помощью @property (nonatomic, retain), вы можете использовать:

self.myProperty = [NSMutableArray arrayWithCapacity:10];

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

1 голос
/ 14 ноября 2008

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

Чтобы убедиться, что это так, вы можете запустить инструменты (утечки) и посмотреть, что он сообщает.

1 голос
/ 14 ноября 2008

Единственная разница, которая может быть причиной этого, состоит в том, что imageWithData: не использует системный кэш изображений, в то время как initWithData: делает. Поэтому, возможно, изображение, созданное с помощью инициализатора, может высвобождать свои данные изображения, когда оно получает предупреждение о памяти, поскольку оно может вернуться в системный кэш, а то, что создано вспомогательным методом, не может.

...