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
.