0

With the help of the instrument, it is shown that CGDataProviderCopyData is using too much memory. How to fix the issue?

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

Instrument screenshot

Abdul Jamil
  • 363
  • 3
  • 13

2 Answers2

1

The problem is that you never release image.

Update your code as follows:

-(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;
}
rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • I already tried to release the image but it introduces a crash. Also it is CGImageRelease(image); not CFImageRelease(image); – Abdul Jamil Mar 11 '17 at 05:18
1

Finally, I was able to solve this. Actually there were few extra unnecessary steps which were causing memory leaks. Here is the updated function:

-(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) returns CGDataProviderRef and that is required as 8th parameter in CGImageCreate function. Above steps to copy image data and then creating CGDataProviderRef were unnecessary.

Abdul Jamil
  • 363
  • 3
  • 13