iPhone - CGBitmapContextCreateImage Утечка, Кто-нибудь еще с этой проблемой? - PullRequest
2 голосов
/ 16 сентября 2009

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

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

-(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];
}

Ответы [ 5 ]

1 голос
/ 02 января 2012

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

CGImageRelease(imageRef);
0 голосов
/ 30 августа 2014

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

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

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

0 голосов
/ 15 июня 2012

Хорошо, проблема здесь в том, что мы определяем возврат из CGBitmapContextCreateImage как CGImageRef, это должен быть CGImage. Причина, по которой ваши выделения (я предполагаю, что 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 голосов
/ 16 сентября 2009

Почему бы не использовать более простой 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;
}

@ конец

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

0 голосов
/ 16 сентября 2009

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

Возможно, вы хотите

return [result autorelease]

...