I have code that I inherited - and there is very liberal use of DispatchQueue.main.async because they were concerned the UI code there wasn't on the main thread - but it already was on the main queue.
The bug I saw, was that if the calling code was already on the main thread, and the function they called also called the DispatchQueue.main.async, it seems like that call was delayed/not-called, and being requeued on the run loop for the next call.
Here's kind of a general - very stripped down - version of what I was experiencing:
var result = 1
override func viewDidLoad() {
super.viewDidLoad()
DispatchQueue.main.async {
print("Before : result = \(self.result)")
self.doStuff()
print("After : result = \(self.result)")
}
}
func doStuff() {
self.result += 1
self.doStuff2()
}
func doStuff2() {
DispatchQueue.main.async {
self.result += 1
self.doStuff3()
}
}
func doStuff3() {
result += 1
}
}
The output is: Before : result = 1 After : result = 2
So it enters doStuff2()
but that function also calls DispatchQueue.main.async
- and therefore, that code never gets executed.
I cleaned it up by removing these extraneous calls - but it took A LONG TIME tracking all of them down.
Is there any better way to debug this?
Also - they said this code worked in iOS 12.
Thanks, Scott