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

Posted

技术标签:

【中文标题】在 Swift 中传递和存储闭包/回调【英文标题】:Passing and storing closures/callbacks in Swift 【发布时间】:2015-06-07 21:56:15 【问题描述】:

我想在 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 方法是否并行异步运行? 是的,他们这样做了。我认为这是最好的做法。 如果你想只传递回调函数而不执行它,去掉两个括号:api.updateCall(item, callback: self.callback) 将方法调用更改为 api.updateCall(item,callback:self.callback) 会导致以下错误:error: function produces expected type '()'; did you mean to call it with '()'? 请随意将我上面的代码复制到 Playground 中自己尝试一下。 【参考方案1】:

我终于找到了工作代码:

// 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")
)

【讨论】:

以上是关于在 Swift 中传递和存储闭包/回调的主要内容,如果未能解决你的问题,请参考以下文章

Swift-- 闭包

Swift 学习- 08 -- 闭包

swift闭包新手详解(新手必看)

Swift学习笔记-继续学习闭包

Swift学习笔记-继续学习闭包

Swift的闭包,枚举,类和结构体