Sobes.tech
Middle

Explique a diferença entre closures escaping e non-escaping, e em que casos é necessário usar @escaping.

sobes.tech IA

Resposta da IA

Fechos por defeito não escapam.

Fecho não escapável:

  • Executa-se no corpo da função à qual é passado.
  • Captura variáveis, mas as liberta após a conclusão da função.
  • Não sobrevive à função.
func doSomething(completion: () -> Void) {
    // Chamada de completion aqui
    completion() 
}

Fecho escapável:

  • Executa-se após o retorno da função à qual é passado.
  • Sobrevive ao corpo da função.
  • Pode ser armazenado para execução posterior, por exemplo, em outra thread ou de forma assíncrona.
  • Captura variáveis, mantendo referências fortes, o que pode levar a ciclos de referências fortes (cycles de retenção). Requer a declaração explícita @escaping.
class DataManager {
    var completionHandlers: [() -> Void] = []

    func addCompletionHandler(handler: @escaping () -> Void) {
        completionHandlers.append(handler)
    }

    func performTasks() {
        // Execução de tarefas...
        for handler in completionHandlers {
            handler() // Chamada dos handlers mais tarde
        }
    }
}

O uso de @escaping é necessário nos seguintes casos:

  • Quando o fecho é armazenado numa propriedade de uma classe ou estrutura.
  • Quando o fecho é passado para outro thread ou operação assíncrona (por exemplo, requisição de rede, GCD, OperationQueue).
  • Quando o fecho é usado como manipulador de evento ou delegado.