2

我有一个应用程序已经在 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。

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

在此处输入图像描述

提前致谢,

尼基尔

4

3 回答 3

6

好的,最后我得到了它的工作。总体而言,这是一次很好的学习体验:)。

实际上,“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错误还是我对它的了解不足。但是现在,我不会在视图更新后立即发布超级视图,并且一切正常:)。

谢谢大家帮助。让我知道我是否在这里做一些奇怪的事情,并且可以以更有效的方式防止这种行为。

最好的,尼基尔

于 2013-11-14T10:22:36.487 回答
1

如果你的 UIView 的高度几乎为零(比如 0.1),drawViewHierarchyInRect: afterScreenUpdates:就会崩溃。因此,请在调用之前检查尺寸。

PS:这只发生在iOS 7上

于 2016-04-01T11:08:38.597 回答
0

由于自动布局问题(我的问题),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;
}
于 2013-11-11T10:46:41.087 回答