UIGraphics 在 iOS 7 上崩溃

Posted

技术标签:

【中文标题】UIGraphics 在 iOS 7 上崩溃【英文标题】:UIGraphics crashes on iOS 7 【发布时间】:2013-11-11 10:09:05 【问题描述】:

我有一个应用程序已经过 ios 6 的广泛测试并且运行良好,而在 iOS 7 上它几乎总是崩溃(但不是 100% 次),主要是 Thread 1: EXC_BAD_ACCESS 错误,没有太多可追踪的。我完全不知道它的下落。我相信我的代码中的某些内容与核心 iOS 方法不兼容。

我能确定的最好的方法是,在注释代码的以下部分后,一切运行良好。

UIGraphicsBeginImageContext(coverView.bounds.size);
[coverView.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *coverImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[UIImageJPEGRepresentation(coverImage, 0.8f) writeToFile:coverFilePath atomically:YES];

//Create thumbnail of cover image
CGSize size = CGSizeMake(116.0f, 152.0f);
UIGraphicsBeginImageContext(size);
[coverImage drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height)];
coverImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
[UIImageJPEGRepresentation(coverImage, 0.8f) writeToFile:coverThumbnailFilePath atomically:YES];

谁能建议我接下来应该去哪里调试?请注意,相同的应用程序在 iOS 6 中运行得非常好,而且这个错误是 iOS 7 特有的。

编辑:附上僵尸堆栈跟踪:到目前为止我无法充分利用它,但可能对专家的眼睛有用:)

提前致谢,

尼基尔

【问题讨论】:

你打开异常断点了吗?我认为不是因为您在谈论 main 中的崩溃。打开它们(这里和谷歌上有很多指南),然后你会找到更具体的线路。 转到Breakpoint Navigator,点击加号和Add Exception breakpoint,然后选择Exception on Throw。然后构建并运行并在此处粘贴更具体的日志。然后我们将能够为您提供帮助。 我把它们打开了,但它们什么也抓不到 请告诉我们coverThumbnailFilePath。当设置断点On Throw 时,您应该在应用程序崩溃时选择行。你做错了什么。应用崩溃时请粘贴日志。这个断点很棒 EXC_BAD_ACCESS 崩溃了。 @TomaszSzulc,我打开了All Exceptions。仍然没有运气。我将很快发布coverThumbnailFilePath,但令人惊讶的是,即使对前两行(即UIGraphicsBeginImageContext(coverView.bounds.size); [coverView.layer renderInContext:UIGraphicsGetCurrentContext()];)的所有内容都进行了评论,崩溃也会发生......我认为UIGraphics或我对它的使用有问题。 【参考方案1】:

好的,我终于让它工作了。总体而言,这是一次很好的学习体验:)。

实际上,“EXE_BAD_ACCESS”的本质确实暗示了内存管理不好,即我请求访问不存在的东西。不幸的是,(或者从逻辑上讲,我之前错过了)泄漏不会找到它。但是当我为zombies 分析我的应用程序时,他们被抓住了。

由于方法导致的问题

   [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];   // iOS 7

或在 iOS 6 中等效

   [self.layer renderInContext:UIGraphicsGetCurrentContext()];

我的应用进度顺序是这样的:

   render view -> update a few things -> request a screenshot be taken on update
   -> update the view -> return to previous view (releasing this one)

现在,因为我要求在更新时拍摄屏幕截图,所以这些方法一直等到视图更新发生。然而,在更新之后,我立即发布了超级视图。因此,这些方法(在等待更新之后)在发布后称为this view。

现在,我不知道这是 Apple 的 iOS 错误还是我对它的理解不够深入。但是现在,我不会在视图更新后立即发布超级视图,并且一切正常:)。

感谢大家的帮助。如果我在这里做了一些奇怪的事情,请告诉我,并且可以以更有效的方式防止这种行为。

最好, 尼基尔

【讨论】:

【参考方案2】:

如果您的 UIView 的高度几乎为零(例如 0.1),drawViewHierarchyInRect: afterScreenUpdates: 将崩溃。因此,在调用之前检查大小。

PS:这只发生在 iOS 7 上

【讨论】:

【参考方案3】:

由于自动布局问题(我的问题),iOS7 几乎没有类似的问题。确保大小存在且有效,例如大小为 0,0,无法创建有效的图形上下文。 我还添加了一个方法,您可以将其作为 UIView 上的一个类别来获取特定视图的屏幕截图。如果在 iOS6 或更低版本上它使用众所周知的-renderInContext:,如果在 iOS7 上它使用新的-drawViewHierarchyInRect:: 确实比第一个更快,如果你也使用它而崩溃。

- (UIImage *) imageByRenderingViewOpaque:(BOOL) yesOrNO 
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, yesOrNO, 0);

    if ([self respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)]) 
        [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
    
    else 
        [self.layer renderInContext:UIGraphicsGetCurrentContext()];
    
    UIImage *resultingImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return resultingImage;

【讨论】:

谢谢安德里亚。这并不能解决我的问题,应用程序仍然崩溃:( 发送消息前检查UIView的状态了吗? 是的...我做到了。它的大小和尺寸都很好

以上是关于UIGraphics 在 iOS 7 上崩溃的主要内容,如果未能解决你的问题,请参考以下文章

NSLayoutConstraints 在 ios 7 上崩溃,但在 ios 8 上没有

来自 xib 的 UIControl 在 ios 7.1 上崩溃

在 iOS 7 上显示 UIImagePickerController 会导致崩溃

Swift 中的本地通知在 iOS 7 上崩溃

XCode 6项目在ios 7.1上segue后崩溃

游戏可在 iOS 8 上运行,但在 iOS 7 中崩溃