可能导致这种“致命异常:CALayerInvalidGeometry CALayer界限包含NaN:[nan nan; nan nan]”崩溃的原因是什么?

时间:2015-02-15 23:01:09

标签: ios iphone cocoa-touch uiview

我有以下一些代码,它只是简单地初始化UIImageView以适合UIImage的比例,因为它可能在当前屏幕尺寸上尽可能大:

CGSize mainScreenSize = [appDelegate mainScreenSize];
CGSize superViewSize = CGSizeMake(mainScreenSize.width, mainScreenSize.height);
CGSize size = [self.image size];

CGFloat xScale = superViewSize.width / size.width;
CGFloat yScale = superViewSize.height / size.height;

CGFloat minimumScale = MIN(xScale, yScale);
self.imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, size.width * minimumScale, size.height * minimumScale)];

self.imageView.image = self.image;
self.frame = CGRectMake(0, 0, size.width * minimumScale, size.height * minimumScale);

[self addSubview:self.imageView];

由于某些原因,当我的某些用户使用该应用时,正在设置frame的{​​{1}}的代码部分会导致以下崩溃:

UIImageView

在检查我的崩溃日志时,错误似乎在所有iOS版本,设备和方向上都是一致的,所以我已经排除了这一点。作为旁注,我用来实现上面的代码:

Fatal Exception: CALayerInvalidGeometry CALayer bounds contains NaN: [nan nan; nan nan]

然后它将自己附加到superview后,我会对UIImageView执行转换以调整它的大小并且我从未收到上述错误(由于解决了由另一个框架引起的错误,我不得不改为新方法)。

我知道上面的错误通常是由除以0或将帧宽和高度设置为0引起的,但我很难弄清楚它是如何发生的。我不认为问题出在imageSize上,因为正如我先前所说,我从来没有遇到过与以前的方法有关的问题。至于主屏幕大小,这是我的app delegate中的方法:

self.imageView = [[UIImageView alloc] initWithImage:image];
self.frame = CGRectMake(0, 0, self.imageSize.width, self.imageSize.height);
[self addSubview:self.imageView];

任何人都知道造成这种情况的原因是什么?

实际上我意识到我在.h:

中设置了我的图像属性
- (CGSize) mainScreenSize
{
    CGSize mainScreenSize = [[UIScreen mainScreen] bounds].size;

    if ([OperatingSystemVersion operatingSystemVersionLessThan:@"8.0"] && UIDeviceOrientationIsLandscape([[UIApplication sharedApplication] statusBarOrientation]))
    {
        mainScreenSize = CGSizeMake(mainScreenSize.height, mainScreenSize.width);
    }

    return mainScreenSize;
}

但我没有在我的.m文件中合成它。这可能导致了这个问题吗?我想知道这种情况在大多数情况下是如何运作的,有时只会崩溃吗?

1 个答案:

答案 0 :(得分:1)

原因是当用户从其照片库中加载照片时,如果没有足够的内存来加载照片,则会为nil返回UIImage。因此,我上面的代码尝试根据UIImageView frame的大小创建nil UIImage,从而导致崩溃。我通过处理从nil返回UIImage UIImagePickerController的案例来解决此问题。