Passagem e armazenamento de fechamentos / retornos de chamada no Swift
Gostaria de fazer o seguinte no código swift:
Preciso ligar para a minha API para atualizar vários itens. Então, eu chamo a API para cada item de forma assíncrona. Cada chamada da API executa uma função de retorno de chamada quando é concluída. Esses retornos de chamada diminuem um contador, de modo que, quando o contador atinge 0, eu sei que todas as minhas chamadas de API são concluídas. Quando o contador atingir 0, eu gostaria de chamar uma função de retorno de chamada final (uma vez, quando todas as chamadas estiverem concluídas), para atualizar minha interface do usuário e assim por diante. Esse retorno de chamada final é passado para o meu serviço no início e armazenado em uma propriedade de classe para execução posterior.
Fonte do Playground Executável:
// 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")
})
O problema é que, com esse código, o retorno de chamada final é chamado na ordem errada.
Aparentemente, a função de retorno de chamada já foi executada e não foi aprovada corretamente. No entanto, foi a única maneira que consegui fazê-lo, sem erros de compilador.
Qualquer ajuda seria muito apreciada - estou preso a isso há dois dias.