Middle
Explique la diferencia entre closures de escape y no escape, y en qué casos es necesario usar @escaping.
sobes.tech AI
Respuesta de la IA
Los cierres por defecto son no escapables.
Cierre no escapable:
- Se ejecuta en el cuerpo de la función a la que se pasa.
- Captura variables, pero las libera después de que la función termina.
- No sobrevive a la función.
func doSomething(completion: () -> Void) {
// Llamada a completion aquí
completion()
}
Cierre escapable:
- Se ejecuta después de que la función a la que se pasa retorna.
- Sobrevive al cuerpo de la función.
- Puede ser almacenado para su ejecución posterior, por ejemplo, en otro hilo o de forma asíncrona.
- Captura variables, manteniendo referencias fuertes, lo que puede llevar a ciclos de referencias fuertes (retains cycles). Requiere la declaración explícita
@escaping.
class DataManager {
var completionHandlers: [() -> Void] = []
func addCompletionHandler(handler: @escaping () -> Void) {
completionHandlers.append(handler)
}
func performTasks() {
// Realización de tareas...
for handler in completionHandlers {
handler() // Llamada a los manejadores más tarde
}
}
}
El uso de @escaping es necesario en los siguientes casos:
- Cuando la clausura se almacena en una propiedad de una clase o estructura.
- Cuando la clausura se pasa a otro hilo o operación asíncrona (por ejemplo, solicitud de red, GCD, OperationQueue).
- Cuando la clausura se usa como manejador de eventos o delegado.