I have some code that looks like this:
DispatchQueue.global(qos: .userInitiated).async {
self.fetchProjects()
DispatchQueue.main.async {
self.constructMenu()
}
}
My question is are the blocks within the global block executed serially? When I add print statements, they always executed in the same order, but I'm not sure if I'm getting lucky as looking at the documentation, it says:
Tasks submitted to the returned queue are scheduled concurrently with respect to one another.
I wonder if anyone can shed any light on this?
EDIT:
Apologies, I don't think I made the question clear. I would like for the method constructMenu
to only be called once fetchProjects
has completed. From what I can tell (by logging print statements) this is the case.
But I'm not really sure why that's the case if what Apple's documentation above says (where each task is scheduled concurrently) is true.
Is code within an async block always executed serially, or is the fact that the code seems to execute serially a result of using DispatchQueue.main
or is it just 'luck' and at some point constructMenu
will actually return before fetchProjects
?
I would like for the method
constructMenu
to only be called oncefetchProjects
has completed. From what I can tell (by logging print statements) this is the case.
Yes, this is the case.
But I'm not really sure why that's the case if what Apple's documentation above says (where each task is scheduled concurrently) is true.
Apple’s documentation is saying that two separate dispatches may run concurrently with respect to each other.
Consider:
DispatchQueue.global(qos: .userInitiated).async {
foo()
}
DispatchQueue.global(qos: .userInitiated).async {
bar()
}
In this case, foo
and bar
may end up running at the same time. This is what Apple means by “Tasks submitted to the returned queue are scheduled concurrently.”
But consider:
DispatchQueue.global(qos: .userInitiated).async {
foo()
bar()
}
In this case, bar
will not run until we return from foo
.
Is code within an async block always executed serially, or is the fact that the code seems to execute serially a result of using
DispatchQueue.main
or is it just ‘luck’ and at some pointconstructMenu
will actually return beforefetchProjects
?
No luck involved. It will never reach the DispatchQueue.main.async
line until you return from fetchProjects
.
There is one fairly major caveat, though. This assumes that fetchProjects
won’t return until the fetch is done. That means that fetchProjects
better not be initiating any asynchronous processes of its own (i.e. no network requests). If it does, you probably want to supply it with a completion handler, and put the call to constructMenu
in that completion handler.