У меня есть массив 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). Таким образом, похоже, что распакованные данные ранее отображенных изображений все еще там. Я знаю, что это не будет проблемой, если я отпущу изображение, когда оно больше не будет видно, и это также освободит распакованный буфер, но, если это возможно, я бы хотел сохранить все изображения и освободить распакованный только данные. Это возможно?