UIImage, освобождение декомпрессионного кэша? - PullRequest
0 голосов
/ 30 октября 2010

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

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

Может ли это быть проблемой? Если так, как я могу обойти это? Моя первая идея состояла в том, чтобы создать копию UIImage всякий раз, когда она назначается ячейке, но похоже, что UIImage не может быть глубоко скопировано. Есть ли способ сказать 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 МБ (все загруженные jpgs, один из них распакован). После всех последующих нажатий потребление памяти увеличивается на ~ 2 МБ (да, я тестировал с изображениями 1024x768). Таким образом, похоже, что распакованные данные ранее отображенных изображений все еще там. Я знаю, что это не будет проблемой, если я отпущу изображение, когда оно больше не будет видно, и это также освободит распакованный буфер, но, если это возможно, я бы хотел сохранить все изображения и освободить распакованный только данные. Это возможно?

Ответы [ 2 ]

2 голосов
/ 30 октября 2010

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

-(void)prepareForReuse
{
      // releasing the image
      self.imageView = nil; // Or release depending on you memory strategy
      self.labelView = nil; // get them all
}
1 голос
/ 30 октября 2010

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

...