2010-10-30 2 views
0

У меня есть массив UIImages, который содержит некоторые .jpg изображения, загруженные из сети при запуске приложения. У меня также есть табличный вид, который показывает некоторые из этих изображений в его ячейках. Проблема в том, что когда я просматриваю таблицу, потребление памяти приложения всегда увеличивается до того момента, когда приложение выходит из строя из-за низких условий памяти. Кажется, что ячейки таблицы многократно используются, поэтому моя теория такова.UIImage, освобождая кеш декомпрессии?

Поскольку UIImageView в ячейке таблицы сохраняет только один из элементов в массиве изображений, когда ячейка повторно используется, и ему назначается новое изображение, то, конечно, ранее не было разрушено ранее используемое изображение (выпуски соты это, но массив все еще сохраняется). Тем не менее, кеш декомпрессии, используемый для хранения данных необработанного изображения (вычисленный при первом отображении UIImage на виде), принадлежит самому UIImage, поэтому он также остается. Но я просто догадываюсь обо всем этом.

Возможно, это проблема? Если да, то как я могу обойти это? Моя первая идея заключалась в том, чтобы создать копию UIImage всякий раз, когда она назначается ячейке, но похоже, что UIImages нельзя полностью скопировать. Есть ли способ сообщить UIImage сохранить сжатые данные jpg в памяти, но выбросить кеш распаковки? (В худшем случае, я думаю, я все еще могу загрузить все изображения и сохранить их в локальных файлах, а затем загрузить их оттуда и полностью освободить UIImages, если они больше не отображаются, но это не похоже на изящное решение.)

-

Я не могу опубликовать исходный код (как это было предложено в комментариях), поскольку это довольно сложно с пользовательскими ячейками таблицы и пользовательских представлений и даже фоновый поток загрузки изображений, но я только что создал небольшое тестовое приложение, и, похоже, оно демонстрирует то же поведение. Вот небольшая функция, которая вызывается, когда пользователь нажимает на UIButton:

- (IBAction)onNext:(UIButton*)sender 
{ 
    static NSMutableArray* images = nil; 
    if (!images) 
    { 
     NSArray* names = [NSArray arrayWithObjects: 
      @"IMG_2957.JPG", 
      @"IMG_2962.JPG", 
      @"IMG_2965.JPG", 
      @"IMG_2970.JPG", 
      @"IMG_2971.JPG", 
      @"IMG_2978.JPG", 
      nil]; 
     images = [NSMutableArray new]; 
     for (int i = 0; i < names.count; ++i) 
      [images addObject:[UIImage imageNamed:[names objectAtIndex:i]]]; 
     int i = 42; 
    } 
    static int current = 0; 

    imageView.image = [images objectAtIndex:current]; 
    ++current; 
} 

Да, я знаю, что массив изображений подтекает, это не точка (в исходном коде я также хочу, чтобы сохранить изображения для весь срок службы приложения и только выпуск при выходе из игры). Но. Согласно Memory Monitor, после первого нажатия (все изображения загружаются, а первый отображается), приложение потребляет ~ 5 МБ (все загруженные jpg, один из них распакован). После всех последующих отводов потребление памяти увеличивается на ~ 2 МБ (да, я тестировал изображения 1024х768). Таким образом, похоже, что распакованные данные ранее отображаемых изображений все еще присутствуют. Я знаю, что это не проблема, если я выпустил изображение, как только он больше не будет виден, и это также приведет к выпуску распакованного буфера, но, если возможно, я хотел бы сохранить все изображения и освободить только распакованные данные. Это возможно?

+0

Можете ли вы показать код? – tadejsv

ответ

1

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

+0

Технически, это не утечка; если я выпустил UIImages, я уверен, что распакованные буферы будут выпущены отлично. Тем не менее, я хотел бы сохранить изображения, я просто хотел бы выпустить распакованные данные. Я редактировал вопрос, чтобы показать код. – imre

+0

Я не думаю, что вы можете это сделать. Я также не думаю, что UIImage будет хранить сжатые данные внутри. Если вы действительно хотите кэшировать данные, я бы предложил использовать NSData для этого. – tia

2

Если вы повторно использовать клетки, убедитесь, что эти клетки осуществлять:

-(void)prepareForReuse 
{ 
     // releasing the image 
     self.imageView = nil; // Or release depending on you memory strategy 
     self.labelView = nil; // get them all 
}