zs2020
zs2020

Reputation: 54543

How to know all dispatched tasks are completed if use dispatch_after in a loop?

Intuitively, I tried something like this:

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
for i in 0..<10 {
    CATransaction.begin()

    let now = DISPATCH_TIME_NOW
    CATransaction.setCompletionBlock {
        var delay = dispatch_time(now, 0)
        dispatch_after(delay, dispatch_get_main_queue(), {
            myfunc()
            dispatch_semaphore_signal(semaphore)
        })
    }

    CATransaction.commit()
}

for i in 0..<10 {
    dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER);
}

//task will be executed after 10 jobs are completed.

However, it seem dispatch_semaphore_wait actually blocks dispatch_after from being executed. How to wait until all 10 async jobs are done?

Thanks!

Upvotes: 0

Views: 145

Answers (1)

Cihan Tek
Cihan Tek

Reputation: 5409

You should be using dispatch groups as in the following example. Make sure to match the number of enter/leave calls otherwise your code in the notify block will never get executed.

let dispatchGroup = dispatch_group_create()

for _ in 0..<10 {
    dispatch_group_enter(dispatchGroup)

    // Do some async tasks
    let delay = dispatch_time(DISPATCH_TIME_NOW, Int64(1 * Double(NSEC_PER_SEC)))

    dispatch_after(delay, dispatch_get_main_queue(), {
        self.myfunc()
        dispatch_group_leave(dispatchGroup)
    })
}

dispatch_group_notify(dispatchGroup, dispatch_get_main_queue()) {
    // The code here will run after all tasks are completed
}

Upvotes: 3

Related Questions