简体   繁体   中英

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:

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

PID: 7439, TID: 362794, Thread name: (none), Queue name: NSOperationQueue 0x60000002f7c0 (QOS: UNSPECIFIED), QoS: 0 Backtrace:

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.

There's not a lot to go on in your question. But if you're using JSON, you're probably retrieving it asynchronously. 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

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.

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

So you should start with the code that fetches that data. Somewhere you are probably calling [[UIApplication sharedApplication] delegate] on a background thread. 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.


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:

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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM