0

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!

zs2020
  • 53,766
  • 29
  • 154
  • 219
  • 1
    Hi @zsong, does this answer your question? http://stackoverflow.com/questions/32642782/waiting-for-multiple-asynchronous-download-tasks – jtbandes Jul 01 '16 at 06:09
  • @jtbandes I tried. But dispatch_group_notify prints out message immediately before async jobs are completed. – zs2020 Jul 01 '16 at 06:16
  • 1
    That depends where you put dispatch_group_leave. It should be after the work is done (like where you currently have the semaphore_signal). – jtbandes Jul 01 '16 at 06:17

1 Answers1

3

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
}
Cihan Tek
  • 5,349
  • 3
  • 22
  • 29