简体   繁体   English

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

[英]Main Thread Checker: UI API called on a background thread: -[UIApplication delegate] Freezes the application

Whenever my application fetch data from JSON it sometimes get this warning and application freezes right away:每当我的应用程序从 JSON 获取数据时,它有时会收到此警告并且应用程序会立即冻结:

Main Thread Checker: UI API called on a background thread: -[UIApplication delegate]主线程检查器:在后台线程上调用的 UI API:-[UIApplication 委托]

PID: 7439, TID: 362794, Thread name: (none), Queue name: NSOperationQueue 0x60000002f7c0 (QOS: UNSPECIFIED), QoS: 0 Backtrace: PID:7439,TID:362794,线程名称:(无),队列名称:NSOperationQueue 0x60000002f7c0(QOS:UNSPECIFIED),QoS:0 回溯:

Can anyone explain how to get rid of it?谁能解释一下如何摆脱它?

It looks like you're updating something on the UI from a thread that's not the main thread.看起来您正在从不是主线程的线程更新 UI 上的某些内容。

There's not a lot to go on in your question.你的问题没有太多可谈的。 But if you're using JSON, you're probably retrieving it asynchronously.但是,如果您使用的是 JSON,则可能是异步检索它。 Make sure that whenever you update the UI from something retrieved, that you wrap it up in a call to the main thread through something like确保每当你从检索到的东西更新 UI 时,你通过类似的东西将它包装在对主线程的调用中

dispatch_async(dispatch_get_main_queue(), ^{
// code to post to UI
});

In the latest versions of swift / Xcode / simulator even examining a UI control for a value can throw this.在最新版本的 swift / Xcode / 模拟器中,即使检查 UI 控件的值也可能抛出此错误。

There are a ton of questions and resources on this very topic.关于这个主题有大量的问题和资源。 For instance:例如:

Thorough Tutorial 完整教程

SO Answer所以答案

But here's what I guess you want:但这是我猜你想要的:

DispatchQueue.main.async {
    // Access UI stuff here
}

When ever my application fetch data from json当我的应用程序从 json 获取数据时

So you should start with the code that fetches that data.因此,您应该从获取该数据的代码开始。 Somewhere you are probably calling [[UIApplication sharedApplication] delegate] on a background thread.在某个地方,您可能在后台线程上调用[[UIApplication sharedApplication] delegate] That's not allowed.那是不允许的。

This likely means you're using your application delegate as a place to store model data.这可能意味着您将应用程序委托用作存储模型数据的地方。 You shouldn't do that.你不应该那样做。 There's almost nowhere in an app that you should reference the application delegate. 应用程序中几乎没有任何地方应该引用应用程序委托。 (This is a very common mistake because it's sometimes done in sample code for simplicity.) (这是一个非常常见的错误,因为为了简单起见,它有时会在示例代码中完成。)

If the program crashes, the location should be in the stacktrace, so I would start by looking there, but otherwise, you'll need to audit your code (likely around JSON parsing or network requests) to find where you're doing this.如果程序崩溃,该位置应该在堆栈跟踪中,所以我会从那里开始查看,否则,您需要审核您的代码(可能围绕 JSON 解析或网络请求)以找到您正在执行此操作的位置。


As noted in the comments below, there is no quick fix to this, and you have almost certainly made your code less stable and more likely to crash in the field.正如下面的评论中所指出的,对此没有快速解决方案,而且几乎可以肯定,您的代码不太稳定,并且更有可能在现场崩溃。 That said, creating a singleton to hold global values in Swift looks like this:也就是说,在 Swift 中创建一个单例来保存全局值看起来像这样:

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

You access it with:您可以通过以下方式访问它:

SomeSingleton.shared.<property>

This does not make anything thread-safe, but if the singleton's properties are immutable ( let ), then fetching them via SomeSingleton.shared can be safely called on any thread, unlike UIApplication.shared.delegate .这不会使任何线程安全,但是如果单例的属性是不可变的( let ),那么可以在任何线程上安全地调用通过SomeSingleton.shared获取它们,这与UIApplication.shared.delegate不同。

Again, it sounds like you have significant concurrency issues in this code, and this is not a quick fix;同样,听起来您在这段代码中存在严重的并发问题,这不是一个快速解决方案; it is just one tool that is often used rather than putting random values on the AppDelegate.它只是一种经常使用的工具,而不是在 AppDelegate 上放置随机值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 主线程检查器:在后台线程上调用的UI API:-[UIApplication委托] - Main Thread Checker: UI API called on a background thread: -[UIApplication delegate] 主线程检查器:在后台线程上调用的 UI API - Main Thread Checker: UI API called on a background thread iOS:主线程检查器:在后台线程上调用UI API: - [UIView retainCount] - iOS: Main Thread Checker: UI API called on a background thread: -[UIView retainCount] -[UIApplication 委托] 只能从主线程调用 - -[UIApplication delegate] must be called from main thread only iOS / Xcode:主线程检查器似乎没有激活,但由于在后台线程上调用UI而导致崩溃? - iOS/Xcode: Main Thread Checker doesn't seem to be activating, but still a crash due to UI being called on background thread? UIApplication 委托只能在主线程中使用 - Swift - UIApplication delegate must be used from main thread only - Swift WARNING-[UIApplication delegate] 只能在主线程中使用 - WARNING-[UIApplication delegate] must be used from main thread only UIApplication.registerForRemoteNotifications() 只能从主线程调用 - UIApplication.registerForRemoteNotifications() must be called from main thread only iOS,ARC:后台线程冻结UI - iOS, ARC: Background thread freezes UI DTCoreText收到警告“在后台线程上调用了UI API” - DTCoreText got a warning of “ UI API called on a background thread”
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM