【问题标题】:UIImage from CGImageRef来自 CGImageRef 的 UIImage
【发布时间】:2023-03-15 22:08:01
【问题描述】:

我正在为一个更复杂的项目尝试一个简单的测试,但我很困惑为什么下面的代码会崩溃并给出 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。

编辑

我做了更多的测试,发现这与 ARC 直接相关,因为我创建了 2 个基本项目,其中仅包括上面的代码。第一个关闭 ARC 并且效果很好。下一个打开 ARC 并且 BAM 崩溃并出现相同的错误。有趣的是,我只有在崩溃前第一次运行项目时才收到实际的日志错误。

 Error: ImageIO: ImageProviderCopyImageBlockSetCallback 'ImageProviderCopyImageBlockSetCallback' header is not a CFDictionary...

【问题讨论】:

    标签: ios ios5 uiimage


    【解决方案1】:

    这行是问题所在:

    CGImageRef imageRef = [[[UIImage alloc]initWithContentsOfFile:imagePath]CGImage];
    

    创建的UIImage 将在此完整表达式之后立即释放(例如,在此行之后)。因此,即使尝试在之后添加 CGImageRetain() 也行不通。

    根本问题是从CGImage 返回的CGImageRef 几乎可以肯定是UIImage 的一个ivar,并且会在UIImage 被释放时被释放。

    解决此问题的通用方法是延长UIImage 的生命周期。您可以通过将UIImage 放入局部变量并在最后一次引用CGImage 之后引用它(例如使用(void)uiimageVar)来实现此目的。或者,您可以在同一行保留CGImageRef,如

    CGImageRef imageRef = CGImageRetain([[[UIImage alloc] initWithContentsOfFile:imagePath] CGImage]);
    

    但如果你这样做了,别忘了在完成后释放imageRef

    【讨论】:

      【解决方案2】:

      这是你写的:

      CGImageRef imageRef = [[[UIImage alloc]initWithContentsOfFile:imagePath]CGImage];
      

      该行创建一个UIImage,获取其CGImage 属性,然后释放UIImage 对象。由于您没有在该行保留CGImage,因此CGImage 的唯一所有者是UIImage。因此,当UIImage 被释放并立即释放时,它也会释放CGImage

      在释放UIImage 之前,您需要保留CGImage。试试这个:

      CGImageRef imageRef = CGImageRetain([[UIImage alloc]initWithContentsOfFile:imagePath].CGImage);
      

      然后在函数结束时:

      CGImageRelease(imageRef);
      

      【讨论】:

      • 太棒了,现在我明白发生了什么。至少我在正确的轨道上。谢谢罗伯。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多