在Swift中传递和存储闭包/回调函数

7
我希望在Swift代码中实现以下内容:
我需要调用API以更新多个项目。因此,我为每个项目异步调用API。每个API调用执行回调函数,表示完成操作。这些回调函数会减少一个计数器,当计数器达到0时,我就知道所有API调用都已完成。当计数器达到0时,我想要调用最终回调函数一次(即所有调用都完成后),以更新我的UI等。最终回调在开始时传递给我的服务,并存储在类属性中以供稍后执行。
可执行的Playground源代码:
// Playground - noun: a place where people can play

class MyService
{
    let api = MyApi()

    var storedFinalCallback: () -> Void = { arg in }
    var queue: Int                      = 0

    func update(items: [String], finalCallback: () -> Void )
    {
        // Count the necessary API calls
        queue               = items.count
        // Store callback for later execution
        storedFinalCallback = finalCallback

        for item in items {
            // Call api per item and pass queueCounter as async callback
            api.updateCall(item, callback: self.callback())
        }
    }

    func callback()
    {
        queue--
        // Execute final callback when queue is empty
        if queue == 0 {
            println("Executing final callback")
            storedFinalCallback()
        }
    }

}

class MyApi
{
    func updateCall(item: String, callback: ())
    {
        println("Updating \(item)")
    }
}

let myItems: [String]     = ["Item1", "Item2", "Item3"]
let myInstance: MyService = MyService()

myInstance.update(myItems, finalCallback: {() -> Void in
    println("Done")
})

问题在于这段代码中,最终的回调被以错误的顺序调用。 如游乐场的控制台输出所示: 显然,回调函数已经被执行,但没有正确传递。不过,这是我能够做到而没有编译器错误的唯一方式。
任何帮助将不胜感激 - 我已经卡在这里两天了。

你的api.update方法是否以异步并行方式运行? - Rengers
是的,他们会这样做。我想这是最佳实践。 - Jan
如果你只想传递回调函数而不执行它,那么请删除这两个括号:api.updateCall(item, callback: self.callback) - Rengers
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Jan
1个回答

6

我终于找到了可用的代码:

// Playground - noun: a place where people can play

class MyService
{
    let api = MyApi()

    var storedFinalCallback: () -> Void = { arg in }
    var queue: Int                      = 0

    func update(items: [String], finalCallback: () -> Void )
    {
        // Count the necessary API calls
        queue               = items.count
        // Store callback for later execution
        storedFinalCallback = finalCallback

        for item in items {
            // Call api per item and pass queueCounter as async callback
            api.updateCall(item, callback: self.callback)
        }
    }

    func callback()
    {
        queue--
        // Execute final callback when queue is empty
        if queue == 0 {
            println("Executing final callback")
            storedFinalCallback()
        }
    }

}

class MyApi
{
    func updateCall(item: String, callback: () -> Void)
    {
        println("Updating \(item)")
        callback()
    }
}

let myItems: [String]     = ["Item1", "Item2", "Item3"]
let myInstance: MyService = MyService()

myInstance.update(myItems, finalCallback: {() -> Void in
    println("Done")
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接