Sobes.tech
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.