iPhone - проблема с памятью UIImage imageScaledToSize

Я провел исследование и несколько раз пытался освободить память UIImage, но безуспешно. Я видел еще одно сообщение в Интернете, где у кого-то была такая же проблема. Каждый раз, когда вызывается imageScaledToSize, ObjectAlloc продолжает расти.

В следующем коде я извлекаю локальное изображение из каталога ресурсов и изменяю его размер с некоторым размытием. Может ли кто-нибудь помочь в том, как освободить память для UIImage, называемых .... scaledImage и labelImage. Это фрагмент кода, в котором iPhone Intruments продемонстрировал накопление ObjectAlloc. Этот фрагмент кода вызывается несколько раз с помощью NSTimer.

//Get local image from inside resource
NSString * fileLocation = [[NSBundle mainBundle] pathForResource:imgMain ofType:@"jpg"];
    NSData * imageData = [NSData dataWithContentsOfFile:fileLocation];
    UIImage * blurMe = [UIImage imageWithData:imageData];

//Resize and blur image
    UIImage * scaledImage = [blurMe _imageScaledToSize:CGSizeMake(blurMe.size.width / dblBlurLevel, blurMe.size.width / dblBlurLevel) interpolationQuality:3.0];
    UIImage * labelImage = [scaledImage _imageScaledToSize:blurMe.size interpolationQuality:3.0];
    imgView.image = labelImage;

person bbullis21    schedule 14.09.2009    source источник
comment
Есть ли еще у кого-нибудь другое возможное решение для этого? Мой objectalloc все еще поднимается в результате вызова imageScaledToSize   -  person bbullis21    schedule 16.09.2009


Ответы (1)


Вы можете заключить вызовы в NSAutoreleasePool, где их результаты будут объединены. Затем вы можете вызвать [сток из пула] для этого пула, и его содержимое будет освобождено, включая изображения.

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

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

UIImage * scaledImage = [blurMe _imageScaledToSize:CGSizeMake(blurMe.size.width / dblBlurLevel, blurMe.size.width / dblBlurLevel) interpolationQuality:3.0];
UIImage * labelImage = [scaledImage _imageScaledToSize:blurMe.size interpolationQuality:3.0];
UIImage * imageCopy = [[UIImage alloc] initWithCGImage:labelImage.CGImage]; // Gives a non-autoreleased copy of labelImage

[pool drain]; // deallocates scaledImage and labelImage

imgView.image = imageCopy; // retains imageCopy

ОБНОВЛЕНИЕ:

Если вышеуказанное по-прежнему вызывает проблемы, см. Решение, которое я опубликовал в этот вопрос. Вопрос заключается в повороте изображения на 90 градусов вместо его масштабирования, но предпосылка та же (отличается просто преобразование матрицы). Использование кода, подобного тому, что я опубликовал, должно дать вам больший контроль над управлением памятью и увести вас от использования недокументированных API, таких как _imageScaledToSize.

person fbrereto    schedule 14.09.2009
comment
А есть ли у вас небольшой пример? Я никогда раньше не работал с NSAutoreleasePool - person bbullis21; 15.09.2009
comment
Возможно, это глупый вопрос, но если я не могу использовать изображения вне пула NSAutorelease, как я смогу использовать imageCopy в вашем примере? - person bbullis21; 15.09.2009
comment
(Я обновил пример, чтобы попытаться сделать его немного более понятным.) imageCopy не помещается в пул автозапуска и потребует от вашего кода управления памятью, что вы и хотите, потому что вы используете его в imgView, который будет длиться дольше, чем пул с автоматическим выпуском. На изображения в пуле автозапуска - labelImage и scaledImage - вы не ссылаетесь после того, как пул опустошен, так что все в порядке. - person fbrereto; 15.09.2009
comment
Извините, после дальнейшего тестирования этот пул выпусков не работал, objectalloc все еще поднимается на вызов UIImage imageScaledToSize - person bbullis21; 16.09.2009
comment
Правильно ли вы выпускаете imgView.image? После выполнения приведенного выше примера кода его значение keepCount будет равно 2, поэтому его однократного выпуска будет недостаточно, и это может объяснить утечку. - person fbrereto; 16.09.2009
comment
Есть ли какое-то решение для этого. Я столкнулся с той же проблемой. - person rkb; 07.10.2009