This application is modifying the autolayout engin

2019-09-11 09:59发布

问题:

I am using this simple code to extract some plain text from a website.

@IBAction func askWeather(sender: AnyObject) {


    let url = NSURL(string: "http://www.weather-forecast.com/locations/" + userField.text! + "/forecasts/latest")!

    let task = NSURLSession.sharedSession().dataTaskWithURL(url) {(data, response, error) -> Void in

        if let urlContent = data{

            let webContent = NSString(data: urlContent, encoding: NSUTF8StringEncoding)

            let wArray = webContent?.componentsSeparatedByString("Day Weather Forecast Summary:</b><span class=\"read-more-small\"><span class=\"read-more-content\"> <span class=\"phrase\">")

            let wCont = wArray![1].componentsSeparatedByString("</span>")

            self.weatherResult.text = wCont[0]


        }
        else{
            print("Sorry could not get weather information")
        }


    }
    task.resume()


}
@IBOutlet var weatherResult: UILabel!
@IBOutlet var userField: UITextField!

And after i press the button to fetch the information nothing happens for several seconds(like 10-20) and then i get the correct result however i get this message in xcode:

This application is modifying the autolayout engine from a background
thread, which can lead to engine corruption and weird crashes.  This will cause an exception in a future release.

I tried reading some posts on others having this problem but they were using threads like async etc. to run their code. Im not really sure what the problem is in my case.

Thank you!

回答1:

I'm guessing that self.weatherResult.text = wCont[0] is modifying something like a UILabel or similar, in which case you're trying to change part of your user interface from a background thread – a big no-no.

Try code like this instead:

dispatch_async(dispatch_get_main_queue()) { [unowned self] in
    self.weatherResult.text = wCont[0]
}


回答2:

    let task = NSURLSession.sharedSession().dataTaskWithURL(url) {(data, response, error) -> Void in

There's your asynchronous thread. Right there. dataTaskWithURL runs in the background and will eventually call the callback function that you passed in. And that is done in the background.