Используя UIImageView, не будучи боров памяти? - PullRequest
1 голос
/ 25 августа 2011
UIImageView *mooshinLogo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"mooshin.png"]];

Я не уверен, правильно ли я создаю экземпляр своего изображения, потому что я читал, что imageNamed не будет очищен из кэша и должен использоваться только для кнопок и маленьких значков. А как насчет фоновых изображений и галерей изображений?

Как правильно реализовать UIImageView?

Ответы [ 4 ]

2 голосов
/ 25 августа 2011

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

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

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

0 голосов
/ 25 августа 2011

Остальные выше правы насчет imageNamed хранит кеш этих изображений. Это особенно верно при использовании файлов NIB. Выпуск Viewcontroller с ImageViews на них напрямую не освобождает связанные изображения.

У меня было приложение, в котором было много изображений с множеством страниц в контроллере навигации. В конце концов, это может произойти сбой при использовании только метода imageNamed. Итак, я теперь использую (нашел здесь на SO) и более:

+ (UIImage *)imageNamed:(NSString *)name {
    //NSLog(@"ImageNamed: %@", name);
    return [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:name ofType:nil]];
}

Теперь я могу контролировать, когда я хочу удалить изображение и сделать его действительно чистым из памяти. В вышеупомянутом приложении я бы на самом деле загружал изображения в viewDidLoad и удалял их в viewDidDisappear. Поэтому, когда я был на глубине 10-15 страниц в NavController, я мог сохранять память нехваткой.

0 голосов
/ 25 августа 2011

[UIImage imageNamed: (NSString *) imageName] - это удобный вспомогательный конструктор.Это означает, что его счетчик хранения увеличивается при инициализации и уменьшается в конце цикла выполнения.Вы можете сделать 100 из них, и они исчезнут из памяти через несколько секунд, если они не будут сохранены чем-то другим.Передав его в UIImageView, UIImageView сохранит его и останется в памяти только до тех пор, пока с ним не будет покончено UIImageView, так что вы делаете это правильно, если только вы не обращаетесь к ОС, кэширующей изображение в «неактивном»БАРАН.Он может делать это за кадром (и будет знать, когда от него избавиться), но вы, безусловно, правильно обрабатываете жизненный цикл объекта.Поскольку вы используете [[Class alloc] init ...] способ создания вашего UIImageView, убедитесь, что вы позже вызовете [mooshinLogo release] или [mooshinLogo autorelease].

(Пожалуйста, игнорируйте это, если выуже знаю.) Objective-C (по крайней мере, для разработки под iOS) является языком подсчета ссылок.Все объекты начинаются с счетчика ссылок или сохраняют счет 1, начиная с момента их выделения.Оттуда они могут быть сохранены ([id retain]), освобождены ([id release]) или помечены для освобождения в конце цикла запуска ([id autorelease]).Как только счет станет равным нулю, он будет освобожден, но вы никогда не должны беспокоиться о его фактическом количестве и использовать только те объекты, которыми владеете (или сохраняете).

Если вы сомневаетесь, вы можете проверить с помощьюСтатический анализатор Clang.Он находит, вероятно, 75% ваших утечек, и у меня было только несколько ложных срабатываний.Либо Build & Analyze, либо Cmd + Shift + B.

0 голосов
/ 25 августа 2011

Не беспокойся!Метод imageNamed возвращает объект с автоматическим освобождением , и он будет выполнять то, что вы называете «очищением из кэша» (т. Е. Его память будет освобождена), когда он больше не нужен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...