【问题标题】:objective c renderInContext crash on background threadObjective c renderInContext 在后台线程崩溃
【发布时间】:2023-04-07 05:00:01
【问题描述】:

我有一个应用程序,其中屏幕在后台线程中连续捕获。这是代码

- (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. 是否有任何其他方式来捕获屏幕(除了 Apple 建议的方式,因为还使用了 renderInContext)。没有渲染的东西...?

【问题讨论】:

  • 你应该在主线程上执行你的 GUI 相关任务
  • 向我们展示您的渲染代码。您是否尝试在未创建它们的线程中使用核心数据对象。您是否在渲染代码中使用非原子属性。这两个和更多都可能导致这种情况。
  • 在调用renderInContext 时,layercontext 中的任何一个是否为零?是否调用了receivedMemoryWarning 方法?
  • @WarrenBurton 我正在编写一种库,因此我的代码不能仅基于主线程。我还有另外两个线程,一个用于捕获另一个用于发送图像。所以是的,也许我正在使用在主线程中创建的核心数据对象。你也能解释一下为什么非原子属性在这里如此重要吗???
  • @ott-- 我不确定层和上下文 cz 尚未检查...但在某些情况下,当崩溃发生时,我会收到“收到内存警告”消息,在某些情况下我不会不。还在尝试... :(

标签: ios cocoa-touch cgcontext screen-capture mainwindow


【解决方案1】:

除了在主线程上执行此方法外,我无事可做。我重新组织了我的线程管理,这样做可以得到很好的结果:

[self performSelectorOnMainThread:@selector(captureScreenOnMainThread) withObject:nil waitUntilDone: YES];最后一个参数在某些情况下可以设置为no...

感谢所有回复。

【讨论】:

    【解决方案2】:

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

    【讨论】:

    • 但是如果我在主线程中进行循环捕获,UI会卡住,对吗?这样它可以工作,但会崩溃,可能是因为它不是线程安全的...... :( ???
    • 这是正确的,当您渲染屏幕截图时,您的 UI 会锁定。意味着您必须找到一种用户友好的方式来实现这一点,例如使用 HUD 或类似的东西。
    • 我有同样的问题,在后台线程 renderincontext 有时会崩溃。你能扩展一下HUD评论吗?
    • @Gamma-Point 通过 HUD,他的意思是您可以使用某种加载器并阻止用户与视图交互。这是 HUD 组件的良好实现的链接github.com/jdg/MBProgressHUD
    猜你喜欢
    • 2019-03-29
    • 2019-02-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-04
    • 2012-12-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多