Middle
Explica diferența dintre closures de escaping și non-escaping și în ce cazuri este necesar să folosiți @escaping.
sobes.tech AI
Răspuns de la AI
În mod implicit, închiderile sunt non-escaping.
Chiar închidere non-escaping:
- Se execută în corpul funcției în care este transmisă.
- Capturează variabile, dar le eliberează după finalizarea funcției.
- Nu supraviețuiește funcției.
func doSomething(completion: () -> Void) {
// Apelarea completion aici
completion()
}
Chiar închidere escapable:
- Se execută după ce funcția în care este transmisă se întoarce.
- Supraviețuiește corpului funcției.
- Poate fi stocată pentru execuție ulterioară, de exemplu, într-un alt fir sau asincron.
- Capturează variabile, păstrând referințe puternice, ceea ce poate duce la cicluri de referințe puternice (retention cycles). Necesită declarație explicită
@escaping.
class DataManager {
var completionHandlers: [() -> Void] = []
func addCompletionHandler(handler: @escaping () -> Void) {
completionHandlers.append(handler)
}
func performTasks() {
// Executarea sarcinilor...
for handler in completionHandlers {
handler() // Apelarea handler-urilor mai târziu
}
}
}
Utilizarea @escaping este necesară în următoarele cazuri:
- Când închiderea este stocată într-o proprietate a unei clase sau structuri.
- Când închiderea este transmisă către alt fir sau operație asincronă (de exemplu, solicitare de rețea, GCD, OperationQueue).
- Când închiderea este utilizată ca handler de eveniment sau delegat.