我正在为一个更复杂的项目尝试一个简单的测试,但是我很困惑为什么下面的代码会崩溃并产生一个EXC_BAD_ACCESS错误?
这是从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);没有什么区别。
我还要指出,这一项目已经启动。
编辑
我做了一些更多的测试,并发现这与ARC直接相关,因为我创建了2个基本项目,其中仅包括上面的代码。第一次与ARC关闭,它运行得很好。下一个用ARC打开,BAM崩溃时也有同样的错误。有趣的是,只有在崩溃前第一次运行项目时,我才得到一个实际的日志错误。
Error: ImageIO: ImageProviderCopyImageBlockSetCallback 'ImageProviderCopyImageBlockSetCallback' header is not a CFDictionary...发布于 2012-10-06 03:11:12
这一行是问题所在:
CGImageRef imageRef = [[[UIImage alloc]initWithContentsOfFile:imagePath]CGImage];创建的UIImage将在这个完整表达式之后立即释放(例如,在这一行之后)。因此,即使以后尝试添加一个CGImageRetain()也不起作用。
根本的问题是,从CGImageRef返回的CGImage几乎可以肯定是UIImage的一个象牙,并且将在UIImage被释放时发布。
修复此问题的一般方法是延长UIImage的生存期。您可以通过将UIImage放在局部变量中并在上次引用CGImage之后引用它(例如,使用(void)uiimageVar)来做到这一点。或者,您可以将CGImageRef保留在同一行中,如
CGImageRef imageRef = CGImageRetain([[[UIImage alloc] initWithContentsOfFile:imagePath] CGImage]);但是,如果您这样做,不要忘了在您完成时释放imageRef。
发布于 2012-10-06 03:10:37
你写了这个:
CGImageRef imageRef = [[[UIImage alloc]initWithContentsOfFile:imagePath]CGImage];该行创建一个UIImage,获取其CGImage属性,然后释放UIImage对象。由于您没有将CGImage保留在该行中,所以CGImage的唯一所有者是UIImage。因此,当UIImage被释放并立即释放时,它也会释放CGImage。
在发布CGImage之前,需要保留UIImage。试试这个:
CGImageRef imageRef = CGImageRetain([[UIImage alloc]initWithContentsOfFile:imagePath].CGImage);然后在函数的末尾:
CGImageRelease(imageRef);https://stackoverflow.com/questions/12756295
复制相似问题