简体   繁体   English

调用CGImage时执行EXEC_BAD_ACCESS

[英]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). EXEC_BAD_ACCESS在第二行发生70%的时间(即有时正常工作)。 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). 从此代码段中看不出问题,即使图像无法加载(图像引用最终将为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). 如下更改您的代码(此外,我假设您正在使用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) PS:如果有人认为CGImage的激进发行不是真实的,我很乐意发布我的错误报告(以及演示实际问题的演示项目)

EDIT: Apple has fixed this, I believe it was in iOS6. 编辑:苹果已修复此问题,我相信它是在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. 修复程序是在定义SDK和标头的情况下进行的,因此您需要链接到iOS6或7-可能还不确定该的部署目标。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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