我有一个已经在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中运行得非常好,而且这个bug非常适合iOS 7。
编辑:附加了僵尸堆栈跟踪:到目前为止我无法使用它,但可能对专家眼睛有用:)
提前致谢,
尼基尔
答案 0 :(得分:5)
好的,最后我开始工作了。这总体上是一个很好的学习经历:)。
实际上,“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)
现在,因为我要求在更新时拍摄屏幕截图,所以这些方法一直等到视图更新发生。但是,在更新后我立即发布了superview。因此,这些方法(在等待更新之后)在发布之后调用this
视图。
现在,我不知道这是Apple的iOS错误还是我对它的不了解。但是现在,我不会在查看更新后立即发布超级视图,一切正常:)。
谢谢你们的帮助。如果我在这里做了一些奇怪的事情,请告诉我,并且可以更有效地防止这种行为。
最好的, NIKHIL
答案 1 :(得分:1)
如果您的UIView的高度几乎为零(例如0.1),drawViewHierarchyInRect: afterScreenUpdates:
将崩溃。所以在打电话之前检查尺寸。
PS:这只发生在iOS 7上
答案 2 :(得分: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;
}