我正在为一个更复杂的项目尝试一个简单的测试,但我很困惑为什么下面的代码会崩溃并给出 EXC_BAD_ACCESS 错误?
I am trying a simple test for a much more complex project but I am baffled as to why the code below is crashing and giving an EXC_BAD_ACCESS error?
这是从 UIView 调用的.
This is called from a UIView.
- (void)testing {
NSString *imagePath = [[NSBundle mainBundle] pathForResource:@"ball.png" ofType:nil];
CGImageRef imageRef = [[[UIImage alloc]initWithContentsOfFile:imagePath]CGImage];
// CGImageRetain(imageRef);
UIImage *newImage = [[UIImage alloc]initWithCGImage:imageRef];
UIImageView *iv = [[UIImageView alloc]initWithImage:newImage];
[self addSubview:iv];
}
我的猜测是 CGImageRef 没有被保留,而是添加了 CGImageRetain(imageRef);没有区别.
My guess is that the CGImageRef is not being retained but adding CGImageRetain(imageRef); makes no difference.
我还应该注意,这个项目已经开启了 ARC.
I should also note that this project has ARC turned on.
编辑
EDIT
我做了更多的测试,发现这与 ARC 直接相关,因为我创建了 2 个基本项目,其中仅包括上面的代码.第一个关闭 ARC 并且效果很好.下一个打开 ARC 并且 BAM 崩溃并出现相同的错误.有趣的是,我只有在崩溃前第一次运行项目时才收到实际的日志错误.
I did a little bit more testing and have discovered that this is directly related to ARC as I created 2 basic projects including only the code above. The first with ARC turned off and it worked perfectly. The next with ARC turned on and BAM crash with the same error. The interesting thing is that I got an actual log error ONLY the first time I ran the project before the crash.
Error: ImageIO: ImageProviderCopyImageBlockSetCallback 'ImageProviderCopyImageBlockSetCallback' header is not a CFDictionary...
这行就是问题所在:
CGImageRef imageRef = [[[UIImage alloc]initWithContentsOfFile:imagePath]CGImage];
创建的 UIImage
将在此完整表达式之后立即释放(例如,在此行之后).因此,即使尝试在之后添加 CGImageRetain()
也行不通.
The created UIImage
will be released immediately following this full-expression (e.g. after this line). So even trying to add a CGImageRetain()
afterwards won't work.
根本问题是CGImage
返回的CGImageRef
几乎肯定是UIImage
的一个ivar,当UIImage
被释放.
The fundamental problem is the CGImageRef
returned from CGImage
is almost certainly an ivar of the UIImage
and will be released when the UIImage
is deallocted.
解决此问题的通用方法是延长 UIImage
的生命周期.您可以通过将 UIImage
放入局部变量并在最后一次引用 CGImage
之后引用它(例如,使用 (void)uiimageVar
).或者,您可以将 CGImageRef
保留在同一行,如
The generic way to fix this is to extend the lifetime of the UIImage
. You can do this by placing the UIImage
into a local variable and referencing it after your last reference to the CGImage
(e.g. with (void)uiimageVar
). Alternatively, you can retain the CGImageRef
on that same line, as in
CGImageRef imageRef = CGImageRetain([[[UIImage alloc] initWithContentsOfFile:imagePath] CGImage]);
但如果你这样做了,别忘了在完成后释放 imageRef
.
But if you do this, don't forget to release the imageRef
when you're done.
这篇关于来自 CGImageRef 的 UIImage的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!