15

I checked what's new in Xcode 9 documentation and I found this

enter image description here

But i didn't understand what is that how I can use this with new Xcode 9.

Sahil Kapoor
  • 11,183
  • 13
  • 64
  • 87
Kishore Suthar
  • 2,943
  • 4
  • 26
  • 44

4 Answers4

36

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

93sauu
  • 3,770
  • 3
  • 27
  • 43
  • 1
    Unfortunately this option is not there in Xcode 11. Do you know where can I find this? – Chetan Hedamba Feb 05 '20 at 07:21
  • I have updated the screenshot for Xcode 11. The only different is that the option to pause on issues has disappear. – 93sauu Feb 05 '20 at 10:39
  • HI i'm using xcode 11.3 how can i pause on main thread isssues in xcode 11.3 any solution please? – iOSDude Mar 03 '20 at 18:25
  • @MIOSY I updated the capture for Xcode 11.3 marking the arrow button to add the breakpoint. – 93sauu Mar 03 '20 at 19:04
  • 1
    The only thing I got in my Xcode 11.3 at runtime is this:: **GPU Frame Capture: Shader performance data maybe unavailable due to deployment target older than device version.** In my app consoe it prints as **UIView setAnimationsEnabled being called from a background thread. Performing any operation from a background thread on UIView or a subclass is not supported and may result in unexpected and insidious behavior** after that my app UI is freeze. Main thread checker is not going to the place where issue is happening. Pls any suggestion?? –  Mar 04 '20 at 07:02
  • @Rahul perhaps you are presenting or configuring a view controller from a background thread so the error is shown. But as the error is from an external library the breakpoint does not work. My advise is uncommenting the code until the error does not appear to find the exact function or line called in a background thread. Be sure that you are calling the correct method of Dispatch framework what is a common mistake – 93sauu Mar 04 '20 at 09:37
  • Here is the soucre code to reproduce this issue: https://drive.google.com/file/d/1FKHPO6SkdOEZ-w_GFnrU5CeeeMQrNT-h/view?usp=sharing You just run this project in device and scan dinosaur.png image(added ion xcode) you will gif playing on top of it. Once if you go back to firstVC that's all app is freezed you can't tap on any button in First VC and also hyou can't start AR scene again. I can't figure out this issue why it's happening after palying GIF can you pleach check and let me know. If anything is required please let me know.. Thanks in advance. –  Mar 04 '20 at 10:06
  • Yes i'm also facing same issue Rahul. UI freezed due to this error. @93sauu can you please help us. – iOSDude Mar 04 '20 at 10:08
  • I have reviewed your code, The first thing is that the method of ARSCNViewDelegate are called in a background thread so if you want to call some method of UIKit you need to call it in the main thread. For other hand the big problem in your code is that when you create the material with a diffuse response the contents cannot be an UIView (super class of GIFImageView). The contents of material only support: UIColor, CGColor, NSNumber, UIImage, etc.... You can review the documentation. – 93sauu Mar 04 '20 at 10:37
23

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.

deadbeef
  • 5,409
  • 2
  • 17
  • 47
  • 1
    Is there a way to disable it for one object in your program? It seems to be reporting nonsense about something that is running on the main thread. – Chewie The Chorkie Apr 19 '18 at 18:26
  • 1
    I too am wondering if anyone knows any pragma clang diagnostic commands to disable this warning on a line-by-line basis – Albert Renshaw Dec 07 '18 at 20:54
  • If you enable this tool, it will cause UI tasks to perform with delay for example, I was trying to display activity indicator and it appeared after some delay because it checks thread before running every UIKit task. Also, it was not detecting accurately for example though I was running on main thread still it was complaining that methods are being on background. – i.AsifNoor Oct 03 '19 at 14:38
2

In XCODE-12 Go to debug then select Scheme then edit scheme Select Run -> Diagnostics

1

Under the Runtime API Checking section, ensure that the Main Thread Checker is enabled to see if you are executing ui methods in a non-UI thread

enter image description here

enter image description here

Shehata Gamal
  • 98,760
  • 8
  • 65
  • 87