【问题标题】:UIGraphics crashes on iOS 7UIGraphics 在 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或我对它的使用有问题。

标签: ios ios7


【解决方案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的状态了吗?
      • 是的...我做到了。它的大小和尺寸都很好
      猜你喜欢
      • 1970-01-01
      • 2013-11-23
      • 2013-09-27
      • 1970-01-01
      • 2013-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-25
      相关资源
      最近更新 更多