0

我有以下代码:

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 70% 的时间发生在第二行(即有时它工作正常)。怎么了?

4

2 回答 2

2

从这个代码片段中问题并不明显,它应该可以正常工作,即使图像无法加载(图像引用最终会为 NULL)。

您可能在其他地方遇到了内存管理问题,并且/或者调试器对崩溃的位置感到困惑。

于 2012-09-11T00:03:21.730 回答
2

如下更改您的代码(另外,我假设您使用的是 ARC)。首先,我将在现有代码中添加注释,然后向您展示如何解决您的问题

// 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

更改您的代码如下

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:如果有人不相信 CGImage 的激进发布是不真实的,我很乐意发布我的错误报告(以及显示问题的演示项目)

编辑:苹果已经解决了这个问题,我相信它在 iOS6 中。他们现在跟踪内部指针的使用并推迟释放内存,直到该指针超出范围。修复是在 SDK 和头文件中定义的,所以你需要链接到 iOS6 或 7 - 可能需要一个部署目标也不确定。

于 2012-09-11T11:29:09.000 回答