aresz
aresz

Reputation: 2649

Updating UI inside a closure via self a bad practice?

I'm fairly new to multithreaded programming and so far I've been updating my UI/views inside closures via self.myview.setTitle, etc.

Here's a sample code of how I'm updating my UI inside handlers/closures

SFSpeechRecognizer.requestAuthorization { (authStatus) in
        switch authStatus
        {
        case .authorized:
            self.recordButton.isEnabled = true
        case .denied:
            self.recordButton.isEnabled = false
            self.recordButton.setTitle("User denied access to speech recognition", for: .disabled)
        case .restricted:
            self.recordButton.isEnabled = false
            self.recordButton.setTitle("Speech recognition is disabled for this device", for: .disabled)
        case .notDetermined:
            self.recordButton.isEnabled = false
            self.recordButton.setTitle("Speech recognition has not yet been authorized", for: .disabled)
        default:
            break;
        }
    }

That's just a sample of what I've been doing but I do that for other tasks too like downloading a json data from a weather API and updating my UIs acordingly, etc.

Now I've heard that this is bad practice and I was hoping to know why. Also, what is the correct way of updating the UI inside a closure thread?

Upvotes: 2

Views: 550

Answers (1)

matt
matt

Reputation: 535306

It is not at all bad practice to update the UI inside a closure.

But it is totally wrong and expressly forbidden to update the UI on any thread but the main thread. And you do not know that whether your closure is called (and running) on the main thread. In general, there is no certainty or likelihood that a completion handler called asynchronously will be called on the main thread.

Therefore, you should either prove that this code is running on the main thread, or else make certain by deliberately getting onto the main thread before updating the UI.

Upvotes: 4

Related Questions