2009-09-16 6 views
2

Есть ли у кого-нибудь еще такая проблема? Я часто изменяю изображения довольно часто с помощью NSTimer. После использования инструментов он не обнаруживает утечек памяти, но мой объектalloc просто продолжает расти. Он указывает непосредственно на CGBitmapContextCreateImage.iPhone - CGBitmapContextCreateImage Leak, Кто-нибудь еще с этой проблемой?

Кто-нибудь знает о решении? или даже возможные идеи?

-(UIImage *) resizedImage:(UIImage *)inImage : (CGRect)thumbRect : (double)interpolationQuality 
{ 
    CGImageRef   imageRef = [inImage CGImage]; 
    CGImageAlphaInfo alphaInfo = CGImageGetAlphaInfo(imageRef); 

    if (alphaInfo == kCGImageAlphaNone) 
     alphaInfo = kCGImageAlphaNoneSkipLast; 

    // Build a bitmap context that's the size of the thumbRect 
    CGContextRef bitmap = CGBitmapContextCreate(
        NULL, 
        thumbRect.size.width, 
        thumbRect.size.height,  
        CGImageGetBitsPerComponent(imageRef), 
        4 * thumbRect.size.width, 
        CGImageGetColorSpace(imageRef), 
        alphaInfo 
        ); 

    // Draw into the context, this scales the image 
    CGContextSetInterpolationQuality(bitmap, interpolationQuality); 
    CGContextDrawImage(bitmap, thumbRect, imageRef); 

    // Get an image from the context and a UIImage 
    CGImageRef ref = CGBitmapContextCreateImage(bitmap); 
    UIImage* result = [UIImage imageWithCGImage:ref]; 

    CGContextRelease(bitmap); // ok if NULL 
    CGImageRelease(ref); 

    return [result autorelease]; 
} 

ответ

0

Просто проверка исправности: вы отпуская обратный UIImage - обычно я бы ожидать, что функция распределения нового объекта (в данном случае UIImage), чтобы иметь создать в имени?

Может быть, вы хотите

return [result autorelease] 

?

+0

Я действительно только что добавил эту строку в мой код пару минут назад. Это тоже не имело значения. CGBitmapContextCreate убивает мой объект allococ – bbullis21

0

Почему бы не использовать более простой UIGraphicsBeginImageContext?

@implementation UIImage(ResizeExtension) 
- (UIImage *)resizedImageWithSize:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)interpolationQuality; 
@end 
@implementation UIImage(ResizeExtension) 
- (UIImage *)resizedImageWithSize:(CGSize)newSize interpolationQuality:(CGInterpolationQuality)interpolationQuality 
{ 
    UIGraphicsBeginImageContext(newSize); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextSetInterpolationQuality(context, interpolationQuality); 
    [image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)]; 
    UIImage *result = UIGraphicsGetImageFromCurrentImageContext(); 
    UIGraphicsEndImageContext(); 
    return result; 
} 

@end

Кроме того, это будет возвращать изображение удерживаемое текущего пула autorelease; если вы создаете много из этих изображений в цикле, вручную распределите и слейте NSAutoreleasePool.

+0

UIGraphicsBeginImageContext не является потокобезопасным –

+0

UIImage не является технически нитевидным (хотя он обычно работает) – rpetrich

+0

Спасибо за советы, но drawInRect не оказывает такого же влияния InterpolationQuality. Это то, что я в основном делал, называя мой сценарий resizeImage, чтобы уменьшить изображение до небольшого разрешения с высоким значением InterpolationQuality и затем изменить его до нормального. Конечным результатом является изображение, подобное Гауссу.Я искал дни, чтобы понять, почему CGBitmapContextCreate создает объект allococ. Благодарим вас за советы, я продолжу работу с вашим фрагментом, чтобы узнать, могу ли я получить тот же конечный результат. Вы знаете какой-либо другой возможный способ? – bbullis21

1

Должно ли вы выпускать imageRef?

CGImageRelease(imageRef); 
0

Хорошо, проблема здесь в том, что определяют отдачу от CGBitmapContextCreateImage как CGImageRef, она должна быть CGImage. Причина, по которой ваши ассигнования (im, предполагающие malloc) постоянно увеличиваются, заключается в том, что сам CGImage никогда не освобождается. Попробуйте приведенный ниже код. Кроме того, нет необходимости автоматически оценивать результат, поскольку он никогда не «Alloc'd».

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

Я набрал это на ПК, поэтому может возникнуть синтаксическая ошибка, если вы поместите ее в XCode; однако это должно сделать трюк.

// Get an image from the context and a UIImage  
CGImage cgImage = CGBitmapContextCreateImage(bitmap);  
UIImage* result = [UIImage imageWithCGImage:cgImage];  
CGContextRelease(bitmap); // ok if NULL  
CGImageRelease(cgImage);  
return result; 
+0

CGBitmapContextCreateImage возвращает CGImageRef, а не CGImage. CGImageRef - это всего лишь typedef CGImage *. Вышеприведенный код не будет компилироваться, и если он будет исправлен, так что CGBitmapContextCreateImage вернет CGImageRef (CGImage *), вы будете освобождать CGImageRef. Ответ неверен. Вы должны рассмотреть возможность его удаления. –

0

Если вы используете сбор мусора, используйте CFMakeCollectable (posterFrame). Если вы используете традиционные управления памятью, это очень просто:

return (CGImageRef)[(id)posterFrame autorelease]; 

Вы бросили CFTypeRef (в данном случае, CGImageRef) в качестве указателя объекта Objective-C, послать ему сообщение -autorelease, а затем отливали результат возвращается к CGImageRef. Этот шаблон работает почти для любого типа, совместимого с CFRetain() и CFRelease().