What is Main Thread Checker in Xcode

It can be enabled/disabled in the diagnostics option of the scheme. Besides, the "Pause on issues" is a comfortable option to debug these problems.

Xcode 11 enter image description here

Xcode <11 Example


From Apple documentation:

The Main Thread Checker is a standalone tool for Swift and C languages that detects invalid usage of AppKit, UIKit, and other APIs on a background thread. Updating UI on a thread other than the main thread is a common mistake that can result in missed UI updates, visual defects, data corruptions, and crashes.

So for example trying to change the text property of a UILabel on a background thread will not work. Apple says that this can result in missed UI updates, visual defects, data corruptions, and crashes. In practice, 99% of the time this will result in random missed UI updates and visual defects (and not crashes).

Crashes would actually be good because we could detect easily such improper use of UIKit, but random visual defects are much harder to detect during development. And that's where the Main Thread Checker comes in.

The Main Thread Checker will help dectect uses of UIKit on a background thread, it will not solve them. Once you've detected a use of UIKit on a background thread, you can solve it using DispatchQueue.

Again, from Apple documentation:

The documentation of URLSession says that the completion closure will be called on a background thread, so this is bad, the Main Thread Checker will help you detect the use of UIKit on a background thread.

let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
   if let data = data {      
      self.label.text = "\(data.count) bytes downloaded"
      // Error: label updated on background thread   
   }
}
task.resume()

Solution: Use DispatchQueue.main to perform UI updates on the main thread.

let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
   if let data = data {
      DispatchQueue.main.async { // Correct
         self.label.text = "\(data.count) bytes downloaded"
      }
   }
}
task.resume()

The solution itself has nothing to do with Xcode, it's a feature of the language. So obviously it was possible in previous versions of Xcode, but before Xcode 9 you didn't have the Main Thread Checker to help you detect the problem.

As @hamish points out, you can also watch the WWDC video for a more detailed explanation.

Tags:

Ios

Swift

Ios12