Middle
Vysvětlete rozdíl mezi escaping a non-escaping closures a v jakých případech je nutné použít @escaping.
sobes.tech AI
Odpověď od AI
Výchozí uzávěry jsou ne-escape.
Ne-escape uzávěr:
- Je vykonáván v těle funkce, které je předáváno.
- Zachytává proměnné, ale uvolňuje je po dokončení funkce.
- Nepřežije funkci.
func doSomething(completion: () -> Void) {
// Volání completion zde
completion()
}
Escape uzávěr:
- Je vykonáván po návratu funkce, které je předáván.
- Přežije tělo funkce.
- Může být uložen pro pozdější vykonání, například v jiném vlákně nebo asynchronně.
- Zachytává proměnné, udržuje silné odkazy, což může vést k silným cyklům odkazů (retain cycles). Vyžaduje explicitní deklaraci
@escaping.
class DataManager {
var completionHandlers: [() -> Void] = []
func addCompletionHandler(handler: @escaping () -> Void) {
completionHandlers.append(handler)
}
func performTasks() {
// Vykonání úkolů...
for handler in completionHandlers {
handler() // Později volání handlerů
}
}
}
Použití @escaping je nutné v následujících případech:
- Když je uzávěr uložen jako vlastnost třídy nebo struktury.
- Když je uzávěr předán do jiného vlákna nebo asynchronní operace (například síťová žádost, GCD, OperationQueue).
- Když je uzávěr použit jako obsluha událostí nebo delegát.