Objective-C:CGDataProviderCopyData 的内存泄漏

Posted

技术标签:

【中文标题】Objective-C:CGDataProviderCopyData 的内存泄漏【英文标题】:Objective-C: Memory leak with CGDataProviderCopyData 【发布时间】:2017-03-10 15:42:36 【问题描述】:

在仪器的帮助下,显示 CGDataProviderCopyData 正在使用过多的内存。如何解决这个问题?

-(UIImage*)imageNamed:(NSString*)name 

UIImage *uiimage = [UIImage imageNamed:name];


CGImageRef originalImage = [uiimage CGImage];
CFDataRef imageData = CGDataProviderCopyData(
         CGImageGetDataProvider(originalImage));
CGDataProviderRef imageDataProvider = CGDataProviderCreateWithCFData(imageData);
CFRelease(imageData);
CGImageRef image = CGImageCreate(
         CGImageGetWidth(originalImage),
         CGImageGetHeight(originalImage),
         CGImageGetBitsPerComponent(originalImage),
         CGImageGetBitsPerPixel(originalImage),
         CGImageGetBytesPerRow(originalImage),
         CGImageGetColorSpace(originalImage),
         CGImageGetBitmapInfo(originalImage),
         imageDataProvider,
         CGImageGetDecode(originalImage),
         CGImageGetShouldInterpolate(originalImage),
         CGImageGetRenderingIntent(originalImage));
CGDataProviderRelease(imageDataProvider);



return [UIImage imageWithCGImage:image];

【问题讨论】:

向我们展示产生此问题的代码。 请查看截图中的代码。没看到截图吗? 请勿将代码作为图片发布。复制并粘贴实际代码。 现在添加代码。屏幕截图来自显示实际问题的仪器。 @AbdulJamil imageData 变量的图像有多大?您希望 imageData 变量使用多少内存? 【参考方案1】:

最后,我能够解决这个问题。实际上,很少有额外的不必要的步骤导致内存泄漏。这是更新后的功能:

-(UIImage*)imageNamed:(NSString*)name 

 UIImage *uiimage = [UIImage imageNamed:name];


 CGImageRef originalImage = [uiimage CGImage];

 CGImageRef image = CGImageCreate(
     CGImageGetWidth(originalImage),
     CGImageGetHeight(originalImage),
     CGImageGetBitsPerComponent(originalImage),
     CGImageGetBitsPerPixel(originalImage),
     CGImageGetBytesPerRow(originalImage),
     CGImageGetColorSpace(originalImage),
     CGImageGetBitmapInfo(originalImage),
     CGImageGetDataProvider(originalImage),
     CGImageGetDecode(originalImage),
     CGImageGetShouldInterpolate(originalImage),
     CGImageGetRenderingIntent(originalImage));

 return [UIImage imageWithCGImage:image];

CGImageGetDataProvider(originalImage) 返回 CGDataProviderRef,这是 CGImageCreate 函数中的第 8 个参数所必需的。上述复制图像数据然后创建 CGDataProviderRef 的步骤是不必要的。

【讨论】:

【参考方案2】:

问题是你永远不会释放image

如下更新您的代码:

-(UIImage*)imageNamed:(NSString*)name 
    UIImage *uiimage = [UIImage imageNamed:name];

    CGImageRef originalImage = [uiimage CGImage];
    CFDataRef imageData = CGDataProviderCopyData(
             CGImageGetDataProvider(originalImage));
    CGDataProviderRef imageDataProvider = CGDataProviderCreateWithCFData(imageData);
    CFRelease(imageData);
    CGImageRef image = CGImageCreate(
             CGImageGetWidth(originalImage),
             CGImageGetHeight(originalImage),
             CGImageGetBitsPerComponent(originalImage),
             CGImageGetBitsPerPixel(originalImage),
             CGImageGetBytesPerRow(originalImage),
             CGImageGetColorSpace(originalImage),
             CGImageGetBitmapInfo(originalImage),
             imageDataProvider,
             CGImageGetDecode(originalImage),
             CGImageGetShouldInterpolate(originalImage),
             CGImageGetRenderingIntent(originalImage));
    CGDataProviderRelease(imageDataProvider);

    UIImage *result = [UIImage imageWithCGImage:image];
    CGImageRelease(image);

    return result;

【讨论】:

我已经尝试释放图像,但它会导致崩溃。也是 CGImageRelease(image);不是 CFImageRelease(image);

以上是关于Objective-C:CGDataProviderCopyData 的内存泄漏的主要内容,如果未能解决你的问题,请参考以下文章

Swift 3.0 令人兴奋,但Objective-C也有小改进--Objective-C的类属性

如何在c++中,调用objective-c

1了解Objective-C语言的起源

Objective-C 和 C++ 的区别有哪些?

Objective-C中的Hello World

C++和Objective-C混编(官方文档翻译)