Xcode 9 update Swift, purple warning

本小妞迷上赌 提交于 2021-02-18 07:46:28

问题


Not sure why after updating to Xcode 9 my project (originally created in Swift 3) is showing purple warnings: UITextField.text must be used from main thread only

I'm only checking in If statement if text field is empty... attaching screenshot.


回答1:


The login manager is running your closure on a thread other than the main thread and you can't use user interface elements off the main thread.

Others have said that it's OK just to read UI properties on side threads and they are probably right, but there is no absolute guarantee of it and, personally, I would heed the warnings. For example, accessing those properties could have side effects. Perhaps their values are cached somewhere and the main thread is in the process of updating or deleting the property just when you want to access it.

The proper way to silence the warnings is to execute your cloasure on the main thread e.g.

LoginManager.checkLoginStatus {
    isLoggedIn in

    DispatchQueue.main.async {

        // Do all your UI stuff here

    }
 }

This way the thread that runs the closure does nothing except schedules the code to run in the main queue which always runs on the main thread.




回答2:


Simply adding DispatchQueue.main.async will prevent this and is recommended in the swift documentation.

DispatchQueue.main.async { 
    //code that caused error goes here
}



回答3:


XCode 9 includes a Main thread checker tool that checks whether any UIKit related stuff is happening on a main thread. It is supposed to prevent the cases where touching UIKit from a background thread, is going to create problems.

Although, it is advisable to keep this tool around, but if its too much a bother for you, you can turn it off:

XCode->Edit Scheme->Target->Diagnostics-> Uncheck RunTime API Checking




回答4:


The problem exactly that it is - you are using UI elements from background thread. Try to modify your code in order to access them from main thread.

Xcode 9 have new feature - it can check problems like this on runtime and report it during execution.

If you REALLY do not want it, you can disable it in scheme settings. Edit Scheme... -> (Select your scheme) -> Diagnostics -> Disable 'Main thread checker'




回答5:


Here is Apple Guideline on Main Thread Checker

  • New in Xcode 9 – Main Thread Checker.
    • Enable detection of UI API misuse from background thread
    • Detects AppKit, UIKit, and WebKit method calls that are not made on the main thread.
    • Automatically enabled during debugging, and can be disabled in the Diagnostic tab of the scheme editor.
    • Main Thread Checker works with Swift and C languages.

Try this: Replace your code with following one, and see. It's a permanent solution, without disabling warning.

@IBAction fund saveButtonTapped(_ sender: Any) {


    LoginManager.checkLoginStatus { isLogged in

        if isLogged {

            // Updates your UIs on main queue
            DispatchQueue.main.async(execute: {

            if self.priceTextField.text == "" {
                GlobalVariables.sharedManager.itemPrice = 0
            } else {
                GlobalVariables.sharedManager.itemPrice = Double(self.priceTextField.text!)!
            }

            if self.titleTextView.text == "" {
                GlobalVariables.sharedManager.expenseTitle = "N/A"
            } else {
                GlobalVariables.sharedManager.expenseTitle = self.titleTextView.text!
            }

            if self.descriptionTextView.text == "" {
                GlobalVariables.sharedManager.expenseDescription = "N/A"
            } else {
                GlobalVariables.sharedManager.expenseDescription = self.descriptionTextView.text!
            }

            if self.categoryPickerTextFld.text == "" {
                GlobalVariables.sharedManager.expenseCategory = "N/A"
            } else {
                GlobalVariables.sharedManager.expenseCategory = self.categoryPickerTextFld.text!
            }


            if self.imageView.image == nil {
                GlobalVariables.sharedManager.expenseSelectedImage = nil
            } else {
                GlobalVariables.sharedManager.expenseSelectedImage = self.imageView.image
            }


            }) 

        }
    }
}



or, you can just disable warning, by disabling main thread checker from your project target

(Xcode Project Target - Below Device List) >> Edit Scheme >> Target >> Diagnostics >> RunTime API Checking - Uncheck




回答6:


The warnings seem overly aggressive as you imply by stating that you are only checking if a textField is empty, not changing anything on the UI. The warning is trying to discourage any use of UI elements off of the main thread, which is not a bad thing of course, but it doesn't take into account edge cases like yours.



来源:https://stackoverflow.com/questions/46490140/xcode-9-update-swift-purple-warning

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!