简体   繁体   中英

Passing and storing closures/callbacks in Swift

I would like to do the following in swift code:

I have to call my api in order to update several items. So I call the api for each item asynchronously. Each api call executes a callback function when it's done. These callbacks decrease a counter, so that when the counter reaches 0 I know that all my api calls are completed. When the counter reaches 0 I would like to call a final callback function (once, when all calls are complete), in order to update my UI and so forth. This final callback is passes to my service in the beginning and stored in a class property for later execution.

Executable Playground source:

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

The problem is that with this code the final callback is called in the wrong order. 从操场上显示的控制台输出。

Apparently the callback function is already executed and not properly passed. However, this was the only way I was able to do it, without compiler errors.

Any help would be really appreciated - I have been stuck on this for two days now.

I finally found the working code:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM