2

I have a function A that contains two other functions B & C. Inside function A I need to call function C once function B has completed. I'm thinking I need to use Grand Central Dispatch's dispatch_group_notify for it, but am not too sure how to use it. I'm calling asynchronous methods in both functions B & C. Here are my functions:

func A() {

    func B() {

    // Three asynchronous functions

    }

    func C() {

    // More asynchronous functions that handle results from func B()

    }

    funcB()
    funcC()
}

EDIT: In func B(), I have three async functions that take awhile to finish. When I use the following method, func C() is still being called before the methods within func B() are completely finished. How do I make sure they're completely finished before the second dispatch group is called?

func A() {

var group = dispatch_group_create()

        dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { () -> Void in

            // async function 1
            // async function 2
            // async function 3
        }

        dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), { () -> Void in

           // async function

        })

}
slider
  • 2,736
  • 4
  • 33
  • 69
  • Sorry, I'm calling asynchronous methods in both B and C – slider Jul 16 '15 at 03:41
  • 1
    Can you provide more on how you are implementing B() and C()? Also do you expect A() to return immediately before B() and C() complete the work? Your code is already calling C() after B(), unless B() is starting another queue inside the method and returns immediately. – hebinda Jul 16 '15 at 04:08
  • See updated code. I have some async functions inside `func C()` that must only be called once the three async functions in `func B()` have finished. – slider Jul 16 '15 at 04:11
  • possible duplicate of [Waiting until two async blocks are executed before starting another block](http://stackoverflow.com/questions/11909629/waiting-until-two-async-blocks-are-executed-before-starting-another-block) – zrzka Jul 16 '15 at 06:04
  • Check answer in linked question or read documentation of `NSOperationQueue`, `NSOperation`, `addDependency(_:)`, ... – zrzka Jul 16 '15 at 06:05
  • @robertvojta Hey robert, please see updated. – slider Jul 20 '15 at 04:41

1 Answers1

1

Here's an example how to wait till your tasks are finished:

func asyncTaskSimulation(delay: NSTimeInterval, completion: (NSTimeInterval) -> ()) {
  dispatch_after(dispatch_time(DISPATCH_TIME_NOW,
    Int64(delay * Double(NSEC_PER_SEC))), dispatch_get_global_queue(QOS_CLASS_UTILITY, 0)) {
      completion(delay)
  }
}

func A() {

  func B(completion: () -> ()) {

    print("Function B start")

    let group = dispatch_group_create()

    dispatch_group_enter(group)
    asyncTaskSimulation(1.0) { (delay) in
      print("First task after \(delay)s")
      dispatch_group_leave(group)
    }

    dispatch_group_enter(group)
    asyncTaskSimulation(2.0) { (delay) in
      print("Second task after \(delay)s")
      dispatch_group_leave(group)
    }

    dispatch_group_enter(group)
    asyncTaskSimulation(0.5) { (delay) in
      print("Third task after \(delay)s")
      dispatch_group_leave(group)
    }

    dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
    completion()

    print("Function B end")
  }

  func C() {
    print("Function C start")
    print("Whatever")
    print("Function C end")
  }

  B() {
    C()
  }

}

A()

Here's the output:

Function B start
Second task after 0.5s
First task after 1.0s
Second task after 2.0s
Function C start
Whatever
Function C end
Function B end
zrzka
  • 20,249
  • 5
  • 47
  • 73
  • When calling function B(), `Cannot reference a local function with captures from another local function` – slider Jul 20 '15 at 17:49
  • I just tested my code in Swift 1.2 & Swift 2.0 and it does work. If you have an issue, it's probably because you did extend it somehow and in a wrong way. No one has a crystal ball, you have to be specific if you need help. Edit your question and show what you did or I can't help. – zrzka Jul 21 '15 at 08:06
  • It may have worked for you. But I had an async function saving objects to a backend in the `asyncTaskSimulation`, and another retrieving those very objects in `func C()`. So the function itself may have worked, in fact it returned all outputs in correct order for me, but it wasn't enough to save and retrieve objects in one call. So I just put a 6 second delay on `func C()` and it worked accordingly. Thanks for your help. – slider Jul 21 '15 at 17:34
  • I prefere use the block way: dispatch_group_notify(group, dispatch_get_main_queue(),^{ print("Function B end") }); – Lapinou Feb 17 '17 at 10:14