我正在尝试一个更复杂的项目的简单测试,但我感到困惑的是为什么下面的代码崩溃并给出一个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];
}
Run Code Online (Sandbox Code Playgroud)
我的猜测是CGImageRef没有被保留但是添加了CGImageRetain(imageRef); 没有区别.
我还应该注意到这个项目已经启用了ARC.
编辑
我做了一些测试,并发现这与ARC直接相关,因为我创建了2个基本项目,仅包括上面的代码.ARC的第一个关闭,它完美地工作.ARC的下一个打开,BAM崩溃并出现同样的错误.有趣的是,我在崩溃前第一次运行项目时才遇到实际的日志错误.
Error: ImageIO: ImageProviderCopyImageBlockSetCallback 'ImageProviderCopyImageBlockSetCallback' header is not a CFDictionary...
Run Code Online (Sandbox Code Playgroud)
Lil*_*ard 13
这一行是问题所在:
CGImageRef imageRef = [[[UIImage alloc]initWithContentsOfFile:imagePath]CGImage];
Run Code Online (Sandbox Code Playgroud)
创建的UIImage将在此完整表达后立即释放(例如,在此行之后).因此,即使尝试添加CGImageRetain()后来也无济于事.
根本问题是CGImageRef返回来CGImage的几乎肯定是一个ivar,UIImage并将在UIImage解除分配时释放.
解决这个问题的一般方法是延长生命周期UIImage.您可以通过将其UIImage放入局部变量并在最后一次引用CGImage(例如with (void)uiimageVar)之后引用它来完成此操作.或者,您可以保留CGImageRef在同一行,如
CGImageRef imageRef = CGImageRetain([[[UIImage alloc] initWithContentsOfFile:imagePath] CGImage]);
Run Code Online (Sandbox Code Playgroud)
但是,如果你这样做,不要忘记imageRef在你完成时释放.
你写了这个:
CGImageRef imageRef = [[[UIImage alloc]initWithContentsOfFile:imagePath]CGImage];
Run Code Online (Sandbox Code Playgroud)
该行创建一个UIImage,获取其CGImage属性,然后释放该UIImage对象.既然你没有留CGImage在那条线上,那么唯一的拥有者CGImage是UIImage.因此,当UIImage释放并立即解除分配时,它CGImage也会解除分配.
您需要CGImage在UIImage发布之前保留.试试这个:
CGImageRef imageRef = CGImageRetain([[UIImage alloc]initWithContentsOfFile:imagePath].CGImage);
Run Code Online (Sandbox Code Playgroud)
然后在函数的末尾:
CGImageRelease(imageRef);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10134 次 |
| 最近记录: |