Nerd For Tech
Published in

Nerd For Tech

Simplifying Dispatch.main.async

Occasionally we need to move results of action from one thread to another.

Typical situation is when you’re doing some calculation on default, or background queue, and propagate changes to main queue(thread).

In case of not using Reactive approach or Combine framework (appeared from iOS 13, macOS 10.15), we need to schedule execution to another thread.

In many cases I call DispatchQueue’s async method:

Such callbacks lead to “nesting”. Plus we shouldn’t forget to use weak or unowned self, otherwise object is going to be retained. Anyway, above code leads to some kind of repetition:

DispatchQueue.main.async { [weak self] in             
guard let self = self else { return }
// Inner code...

Which is unpleasant to me because of brackets :). Well we can use code snippets in Xcode to make life easier. Otherwise it’s possible to create some protocol (I called it MainThreadRunnerType) and smart scheduling method(runOnMain) on UI thread:

So in such case "repetition" is going to look in the following way:runOnMain { [weak self] in
runOnMain { [weak self] in
guard let self = self else { return }

Let’s add an extension to the protocol, allowing to weakly call object’s method. If I am not mistaken, I saw the original idea in RxCocoa:

In the above code Self is used in extension, therefore it is possible to use protocol as a type and weak reference is created for the object.

Let’s see some example:

There is also “code duplication” pattern which could be resolved by Xcode’s code snippet. However, it looks better:

runOnMainWeakly(method: type(of: self).displayEndMessage) runOnMainWeakly(method: type(of: self).displayMessage2(_:), 
parameter: "Messsage 2nd")

In this article we managed to simplify Dispatch.main.async call pattern.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store