I have code set up like below. It is my understanding that queue1 should finish all operations THEN move to queue2. However, as soon as my async operation starts, queue2 begins. This defeats the purpose of GCD.. what am I doing wrong? This outputs:
did this finish
queue2
then some time later, prints success from image download
..I want to make it clear that if I put in other code in queue1, such as print("test") or a loop 0..10 printing i, all those operations will complete before moving to queue2. It seems the async download is messing with it, how can I fix this? There is no documentation anywhere, I used This very hepful guide from AppCoda http://www.appcoda.com/grand-central-dispatch/
let queue1 = DispatchQueue(label: "com.matt.myqueue1")
let queue2 = DispatchQueue(label: "com.matt.myqueue2")
let group1 = DispatchGroup()
let group2 = DispatchGroup()
let item = DispatchWorkItem{
// async stuff happening like downloading an image
// print success if image downloads
}
queue1.sync(execute: item)
item.notify(queue1, execute: {
print("did this finish?")
})
queue2.sync {
print("queue2")
}
let item = DispatchWorkItem{
// async stuff happening like downloading an image
// print success if image downloads
}
OK, defines it, but nothing runs yet.
queue1.sync(execute: item)
Execute item
and kick off its async events. Immediately return after that. Nothing here says "wait for those unrelated asynchronous events to complete." The system doesn't even have a way to know that there are additional async calls inside of functions you call. How would it know whether object.doit()
includes async calls or not (and whether those are async calls you meant to wait for)? It just knows when item
returns, continue.
This is what group1
is supposed to be used for (you don't seem to use it for anything). Somewhere down inside these "async stuff happening" you're supposed to tell the system that it finished by leaving the group. (I have no idea what group2
is for. It's never used either.)
item.notify(queue1, execute: {
print("did this finish?")
})
item
already finished. We know it has to have finished already, because it was run with sync
, and that doesn't return until its item has. So this block will be immediately scheduled on queue1
.
queue2.sync {
print("queue2")
}
Completely unrelated and could run before or after the "did this finish" code, we schedule a block on queue2
.
What you probably meant was:
let queue1 = DispatchQueue(label: "com.matt.myqueue1")
let group1 = DispatchGroup()
group1.enter()
// Kick off async stuff.
// These usually return quickly, so there's no need for your own queue.
// At some point, when you want to say this is "done", often in some
// completion handler, you call group1.leave(), for example:
... completionHandler: { group1.leave() }
// When all that finishes, print
group.notify(queue: queue1) { print("did this finish?") }