带有successHandler的Swift函数,使用successHandler调用其他函数

时间:2018-03-27 18:39:11

标签: swift closures

我有一个方法A,它在闭包中返回一个结果。现在,此函数使用successClosure迭代其他方法B.我该怎么做?

伪代码:

func methodA(successHandler: @escaping () -> (Int)){

   for object in objects{
      object.methodB{
        successHander()
      }
   }

}

func methodB(successHandler: @escaping () -> ()){
   successHander(42)
}

1 个答案:

答案 0 :(得分:1)

让我们从一个更好的例子开始,使用真正的异步任务。

以下将创建10个异步任务,它们以0到10秒的随机间隔调用其成功处理程序:

func methodA(successHandler: @escaping (String) -> ()){
    let objects = (1...10).map { "Block \($0)" }

    for object in objects {
        methodB(message: object) { print($0) }
    }

    successHandler("Everything done")
}

func methodB(message: String, successHandler: @escaping (String) -> ()){
    let randomSecs = DispatchTimeInterval.seconds(Int(arc4random_uniform(10)))
    DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + randomSecs) {
        successHandler(message)
    }
}

methodA {
    print($0)
}

sleep(12000)

使用DispatchGroup等待所有子任务完成并在完成块中返回结果:

func methodA(successHandler: @escaping (String, [String]) -> ()){
    let objects = (1...10).map { "Block \($0)" }

    let queue = DispatchQueue.global(qos: .background)
    let dispatchGroup = DispatchGroup()

    var results: [String] = []

    for object in objects {
        dispatchGroup.enter()
        methodB(message: object) {
            print($0)
            results.append($0)
            dispatchGroup.leave()
        }
    }

    dispatchGroup.notify(queue: queue) {
        successHandler("Everything done", results)
    }
}

func methodB(message: String, successHandler: @escaping (String) -> ()){
    let randomSecs = DispatchTimeInterval.seconds(Int(arc4random_uniform(10)))
    DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + randomSecs) {
        successHandler(message)
    }
}

methodA {
    print($0, $1)
}

sleep(12000)

请注意,这是控制台应用程序的示例。在UI应用程序(MacOS / iOS)中,您可以使用DispatchQueue.main作为通知队列,但您不会需要sleep