2013-02-28 85 views
4

我有一个应用程序,屏幕在后台线程中不断捕获。这里是代码objective c renderInContext在后台线程崩溃

- (UIImage *) captureScreen { 

    UIWindow *keyWindow = [[UIApplication sharedApplication] keyWindow]; 
    CGRect rect = [keyWindow bounds]; 
    UIGraphicsBeginImageContext(rect.size); 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    [[keyWindow layer] renderInContext:context]; 
    UIImage *img = UIGraphicsGetImageFromCurrentImageContext(); 

    UIGraphicsEndImageContext(); 

    UIDeviceOrientation orientation = [UIApplication sharedApplication].statusBarOrientation; 
    if ((orientation == UIInterfaceOrientationLandscapeLeft) || (orientation == UIInterfaceOrientationLandscapeRight) || (orientation==UIInterfaceOrientationPortraitUpsideDown)) { 
     img=[self rotatedImage:img]; 
    } 
    return img; 
} 

它适用于捕获一次或两次。但过了一段时间,应用程序崩溃总是在同一行[[keyWindow layer] renderInContext:context];,它给出EXC_BAD_ACCESS (code=1, address=0x8)消息。我到处搜索,没有任何用处。只发现renderInContext在后台线程中工作时存在内存泄漏问题。但正如你所理解的,并不能解决我的问题:)。 因此有3个问题: -

  1. 这个崩溃(问题)的原因是什么?

  2. 我该怎么办?

  3. 是否有任何其他方式来捕捉屏幕(旁边苹果建议,因为renderInContext也被使用)。没有渲染的东西...?

+0

您应该在主线程 – nsgulliver 2013-02-28 12:13:38

+0

上执行您的GUI相关任务向我们展示您的渲染代码。你是否试图在未创建它们的线程中使用核心数据对象。你在渲染代码中使用了非原子属性吗?这些和更多都可能导致这种情况。 – 2013-02-28 12:38:39

+0

当调用'renderInContext'时,是否有'layer'或'context' nil?是否调用了receivedMemoryWarning方法? – 2013-02-28 13:15:30

回答

8

-renderInContext:不是线程安全的,你不能从后台线程调用它。你必须在主线程上进行绘图。

+0

但是,如果我在主线程中进行循环捕获,UI会卡住,对吗?这种方式有效,但崩溃,可能是它不是线程安全的原因... :(??? – Garnik 2013-02-28 13:23:53

+0

这是正确的,当UI渲染屏幕截图时,UI会锁定。意味着你必须找到一个用户友好的方式来实现这一点,抛出一个HUD或类似的东西。 – 2013-04-04 15:25:47

+0

我有同样的问题,在后台线程renderincontext有时崩溃。你可以扩展HUD评论吗? – 2013-04-06 04:57:33

3

我无事可做,只能在主线程上执行此方法。我改组我的线程管理和能取得良好的效果,我这样做:

[self performSelectorOnMainThread:@selector(captureScreenOnMainThread) withObject:nil waitUntilDone: YES];最后参数可以为所有响应设置为无在某些情况下...

感谢。