Home > Mobile >  Why do I need to manage/update main thread if delegate is already being used
Why do I need to manage/update main thread if delegate is already being used

Time:05-19

I have an async api call and I'm using the delegate pattern and assigned a protocol methods to handle what to do with the data when we receive the response from api

didWeatherUpdate

I implement this in a delegate. The way I understand it, This method which I use to update the UI with data from api won't fire until the async network request is done.

My question is why does the main thread is need to be explicitly told that it is an async process. if the function will not be called until the data is ready after api call is complete. My assumption is that when the data is ready the function fires then added to queue that main thread works through. It seems so extra coming from a full stack background

  func didWeatherUpdate(_ weatherManager: WeatherManager,_ weather: WeatherModel){
        print("\(weather.temperature) from the controller")
        DispatchQueue.main.async{
            self.temperatureLabel.text = weather.temperatureString
        }

CodePudding user response:

Here is your function

func didWeatherUpdate(_ weatherManager: WeatherManager,_ weather: WeatherModel){
    print("\(weather.temperature) from the controller")
    DispatchQueue.main.async{
        self.temperatureLabel.text = weather.temperatureString
    }
}

This function is called on the background thread. The print line is done on that thread.

If you tried to do self.temperatureLabel.text = weather.temperatureString as the next line without wrapping it in the DispatchQueue async block, then it would run immediately in the background and would cause a runtime warning as you are not allowed to update the UI in the background.

To update the UI, you need to wrap your line in a block and send it to the main queue and not wait for it. That's exactly what this does

DispatchQueue.main.async {
    self.temperatureLabel.text = weather.temperatureString
}

The async here is not telling the main queue that the data fetch was async. It's saying that you want to send the block to the main queue asynchronously and not have the background thread wait for the UI to update. If you had a print line right after this, it could happen before the UI updated.

If you wanted the background thread to wait for the UI, you would use DispatchQueue.main.sync.

  • Related