Pregunta Pasar y almacenar cierres / devoluciones de llamadas en Swift


Me gustaría hacer lo siguiente en código swift:

Tengo que llamar a mi api para actualizar varios elementos. Así que llamo a la api para cada elemento de forma asíncrona. Cada llamada a la API ejecuta una función de devolución de llamada cuando se realiza. Estas devoluciones disminuyen un contador, de modo que cuando el contador llega a 0, sé que todas mis llamadas a la API se completaron. Cuando el contador llegue a 0, me gustaría llamar a una función de devolución de llamada final (una vez, cuando todas las llamadas estén completas), para actualizar mi interfaz de usuario y así sucesivamente. Esta última devolución de llamada se pasa a mi servicio al principio y se almacena en una propiedad de clase para su posterior ejecución.

Fuente de juego ejecutable:

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

El problema es que con este código, la devolución de llamada final se llama en el orden incorrecto. As the console output from the playground shows.

Al parecer, la función de devolución de llamada ya está ejecutada y no se pasa correctamente. Sin embargo, esta era la única forma en que podía hacerlo, sin errores de compilación.

Cualquier ayuda sería realmente apreciada. He estado atrapado en esto por dos días.


5
2018-04-02 20:05


origen


Respuestas:


Finalmente encontré el código de trabajo:

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

6
2018-04-04 12:53



Preguntas populares