开发者

Objective-C imageWithCGImage memory leak

开发者 https://www.devze.com 2023-04-11 02:36 出处:网络
I want to save all my phot开发者_如何学编程os from assets to some folder. Doing this in loop by:

I want to save all my phot开发者_如何学编程os from assets to some folder. Doing this in loop by:

ALAssetRepresentation *representation = [asset defaultRepresentation];
CGImageRef imageRef = [representation fullResolutionImage]; 

ALAssetOrientation orientation = [representation orientation];
UIImage *image = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:(UIImageOrientation)orientation];

CGFloat compressionQuality = 1.0;
NSData *imageData = [NSData dataWithData:UIImageJPEGRepresentation(image, compressionQuality)];
[imageData writeToFile:path atomically:YES];

CGImageRelease(imageRef);

I have Automatic Reference Counting enabled. This code is inside autorelease pool. It has a memory leak of CGImageRef objects. If i'll make

CGImageRelease(imageRef);
CGImageRelease(imageRef);

twice there is no memory leak. Why? Anybody can help me?


This is one unbelievable bug in iOS. Apparently when you create an UIImage using imageWithCGImage: method it retains the original CGImageRef which never gets released even if you release the UIImage itself (like set it to nil if you use ARC)! So you have to release it explicitly like this:

UIImage *image = [UIImage imageWithCGImage:imageRef scale:1.0 orientation:(UIImageOrientation)orientation];
CGImageRelease(imageRef);
...
CGImageRelease(image.CGImage);
image = nil; // once you are done with it

Cost me full day of digging around until I came across this question that actually contained the answer. Who can I send the bill at Apple for all the time I spent on debugging this unspeakable bug?

CORRECTION: This was not an iOS bug, this was my stupid mistake. At some point I have "hijacked" dealloc method of UIImage through a private category to do some debugging and forgot about it. This is a WRONG thing to do, since the dealloc on the actual object never gets called in that case. So the end result is expected: UIImage didn't have a chance to do all the housekeeping it's supposed to do when being deallocated. NEVER EVER override dealloc through a private category.

0

精彩评论

暂无评论...
验证码 换一张
取 消