主线程检查器:在后台线程上调用UI API: - [UIApplication delegate]冻结应用程序

时间:2017-10-26 14:25:05

标签: ios swift multithreading api background-thread

每当我的应用程序从JSON获取数据时,它有时会收到此警告并立即冻结应用程序:

  

主线程检查器:在后台线程上调用UI API: - [UIApplication delegate]

     

PID:7439,TID:362794,主题名称:(无),队列名称:NSOperationQueue 0x60000002f7c0(QOS:UNSPECIFIED),QoS:0   回溯:

任何人都可以解释如何摆脱它吗?

3 个答案:

答案 0 :(得分:2)

看起来你正在从一个不是主线程的线程上更新UI上的内容。

你的问题不是很多。但是,如果您使用的是JSON,则可能是异步检索它。确保无论何时从检索到的内容更新UI,您都可以通过类似

之类的内容调用主线程来将其包装起来。
dispatch_async(dispatch_get_main_queue(), ^{
// code to post to UI
});

答案 1 :(得分:2)

  

我的应用程序何时从json

获取数据

因此,您应该从获取该数据的代码开始。某个地方你可能在后台线程上调用[[UIApplication sharedApplication] delegate]。这是不允许的。

这可能意味着您将应用程序委托用作存储模型数据的位置。你不应该这样做。 There's almost nowhere in an app that you should reference the application delegate.(这是一个非常常见的错误,因为为了简单起见,它有时会在示例代码中完成。)

如果程序崩溃,那么该位置应该在堆栈跟踪中,所以我先从那里开始查看,否则,您需要审核您的代码(可能是围绕JSON解析或网络请求)以找到您所在的位置这样做。

正如下面的评论所述,没有快速解决方案,您几乎肯定会使您的代码不稳定,并且更容易在现场崩溃。也就是说,在Swift中创建一个用于保存全局值的单例看起来像这样:

class SomeSingleton {
    static let shared = SomeSingleton()
    // Properties you want to be available via the singleton
}

您可以通过以下方式访问它:

SomeSingleton.shared.<property>

这不会使线程安全,但如果单例的属性是不可变的(let),那么可以在任何线程上安全地调用通过SomeSingleton.shared获取它们,这与UIApplication.shared.delegate不同。

同样,听起来你在这段代码中有很多并发问题,这不是一个快速修复;它只是一个经常使用的工具,而不是在AppDelegate上放置随机值。

答案 2 :(得分:1)

在swift / Xcode / simulator的最新版本中,即使检查值的UI控件也可以抛出此值。

关于这个话题,有很多问题和资源。例如:

Thorough Tutorial

SO Answer

但这就是我想你想要的东西:

break-inside