简体   繁体   中英

EXEC_BAD_ACCESS on calling CGImage

I have the following code:

UIImage *img = [UIImage imageNamed:@"BRBlueCircleMask"];
CGImageRef activeCirleMaskImage = img.CGImage;
activeCirleMaskLayer = [CALayer layer];
activeCirleMaskLayer.frame = CGRectMake(0, 0, 50, 50);
activeCirleMaskLayer.contents = CFBridgingRelease(activeCirleMaskImage);

EXEC_BAD_ACCESS happens at the second line in 70% of times (ie sometimes it works properly). What is wrong?

The problem isn't evident from this code snippet, which should work fine, even if the image fails to load (the image ref will just end up being NULL).

It's likely you have a memory management issue somewhere else that's manifesting in this way, and/or the debugger is confused about the location of the crash.

Change your code as follows (also, I am assuming you are using ARC). First I will add comments to the existing code, then show you how to fix your problem

// While this is a strong reference, ARC can release it after 'img.CGImage' (I have an accepted bug on this)
UIImage *img = [UIImage imageNamed:@"BRBlueCircleMask"];
// ARC should cause 
CGImageRef activeCirleMaskImage = img.CGImage;
 // you do not own the image, and a current ARC bug causes this object SOMETIMES to get released immediately after the assignment!!!
activeCirleMaskLayer = [CALayer layer];
activeCirleMaskLayer.frame = CGRectMake(0, 0, 50, 50);
activeCirleMaskLayer.contents = CFBridgingRelease(activeCirleMaskImage); // You are releasing an object here you don't own, which is the root cause of your problem

Change your code as follows

UIImage *img = [UIImage imageNamed:@"BRBlueCircleMask"];
// want to get the CGImage copied ASAP
CGImageRef activeCirleMaskImage = CGImageCreateCopy(img.CGImage); // now you own a copy
activeCirleMaskLayer = [CALayer layer];
activeCirleMaskLayer.frame = CGRectMake(0, 0, 50, 50);
activeCirleMaskLayer.contents = CFBridgingRelease(activeCirleMaskImage); // OK now, its your copy

PS: if anyone disbelieves that the aggressive release of the CGImage is not real, I'd be glad to post my bug report (along with a demo project showing the problem in action)

EDIT: Apple has fixed this, I believe it was in iOS6. They now track use of internal pointers and hold off releasing the memory until that pointer has gone out of scope. The fix was in the was the SDK and headers were defined, so you need to link to iOS6 or 7 - maybe need a deployment target of that too not sure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM