I realized that there is a difference between using DispatchQueue.main.asyncAfter(deadline: .now()) and perform(_:with:afterDelay:0) when main queue is "busy".
Note that perform(_:with:afterDelay:) is called from main queue in my situation.
Seem like DispatchQueue.main.asyncAfter(deadline: .now()) performs the task immediately at the next run loop without caring about main queue but perform(_:with:afterDelay:) with 0 delay will wait and perform the task only when main queue is "free" (maybe it won't be called at the next run loop).
According to Apple document for perform(_:with:afterDelay:)
Specifying a delay of 0 does not necessarily cause the selector to be performed immediately. The selector is still queued on the thread’s run loop and performed as soon as possible.
I'm not sure that I understand them right so could anyone help me to explain exactly what is the difference under the hood between them? What does performed as soon as possible mean?
I found a same question here but seem like it's not what I want.