2016-02-03 2 views
3

У меня проблема с памятью и изображениями, которые я оживляю. Во-первых, я использую ARC. На моем первом экране у меня есть около 60 изображений для анимации. Я использую этот код для анимации:UIImageView Анимация слишком много потребления памяти

NSMutableArray *images = [[NSMutableArray alloc] init]; 
int animationImageCount = 61; 
for (int i = 1; i < animationImageCount; i++) { 
    [images addObject:[UIImage imageNamed:[NSString stringWithFormat:@"s-%d", i]]]; 
} 
self.fullAnimatedImage = [UIImage imageNamed:[NSString stringWithFormat:@"s-%d", animationImageCount - 1]]; 

self.animatedImageView.image = self.fullAnimatedImage; 
self.animatedImageView.animationImages = [NSArray arrayWithArray:images]; 
self.animatedImageView.animationDuration = images.count/30; 
self.animatedImageView.animationRepeatCount = 1; 
[self.animatedImageView startAnimating]; 

// since there is no official callback method when UIImageView animation completes, 
// we can just call a method after animation time has passed 
[self performSelector:@selector(animationFinished) withObject:nil 
      afterDelay:self.animatedImageView.animationDuration]; 

Проблема заключается в том, что потребление памяти составляет около 300 Мб и, конечно, он выходит из строя на iPhone 4. Когда я закомментировать эту часть кода, потребление памяти составляет около 40 МБ, ничего страшного. Я пробовал устанавливать свойство изображения в nil и ничего. Я попытался поместить его в @autoreleasepool {}, но он не выпускает его содержимое. У вас есть идеи, как оптимизировать это?

+0

Что такое fullAnimatedImage? Когда вы уже задали массив изображений для анимации, вы снова задали изображение для изображения? –

+0

Да, вы правы, мне это не нужно. Проблема в том, что нельзя использовать метод fromPath из UIImage, потому что я использую xcassets, и этот метод не кэширует изображения. – Flipper

+0

Какова продолжительность анимации? Половина секунды для каждого изображения? Было бы проще/лучше использовать таймер для переключения между изображениями? Таким образом, вам не нужно хранить фактические изображения в памяти. Вы можете просто загрузить их по одному. В качестве альтернативы, вы могли бы обернуть эту анимацию как видео или что-то еще и использовать это вместо этого? – Fogmeister

ответ

3

Вам следует попробовать заменить [UIImage imageNamed:] на [UIImage imageWithContentsOfFile:].

Из документов:

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

+0

У меня есть изображения в xcassets, я не могу использовать эту функцию – Flipper

+0

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

+0

Это ответ должен быть отмечен как принятый! – dip

0

Насколько велико каждое изображение, которое вы загружаете (пиксель мудрый и размер файла мудрый)?

Ваш лучший выбор - оптимизировать изображения, чтобы уменьшить их размеры файлов/требования к памяти. Попробуйте использовать jpg вместо png, если вы еще этого не сделали. Если они являются частью видеопоследовательности, вы можете безопасно уменьшить свое качество дальше, не имея подделки по воспринимаемому качеству.

+0

Каждое изображение составляет 3,5 kb. Я попробую – Flipper

+0

Изображения несжатые в памяти, вы смотрите на сжатый размер, который полностью вводит в заблуждение. – MoDJ

0

Так что после определенного периода времени я решил пойти по-другому. Из 60 изображений я создал 10 изображений. У меня нет каждого изображения для каждого объекта, кроме одного изображения для всех объектов. Например, если у вас есть 3 машины, и изображение для каждого автомобиля, а еще одно n изображений для перемещения каждые три точки влево, это теперь одно изображение для всех трех автомобилей. Для одних и тех же объектов я создал одно целое изображение. После этого я создал изображение для каждого изображения. Мне нужно было знать для каждого изображения то, что было конечной позицией объекта изображения. Например, автомобиль идет справа налево. Поэтому я разместил это изображение со всеми моими машинами справа, вне поля зрения. И это логика для каждого другого изображения. После этого я просто оживляю позицию UIImageViews. Надеюсь, это поможет кому-то.

0

Проблема в вашем коде с базовым подходом. Вы просто не можете хранить все декодированные изображения в памяти одновременно. Я написал специальный пост в блоге по этому вопросу, который вы можете прочитать here. Решение заключается в использовании другого подхода, так что вы одновременно сохраняете только один кадр декодированных изображений в памяти. Это означает, что при необходимости необходимо динамически загружать фреймы данных.

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