0Pricing
Swift Academy · Lekcja

Domknięcia uciekające

Przechowywanie domknięć, które żyją dłużej niż ich funkcja.

Domknięcia uciekające to bezpłatna lekcja Swift Academy na CoddyKit. To lekcja 2 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Swift Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Swift Academy zawiera 4 lekcji w sumie.

Uciekające a nieuciekające

Domyślnie parametr będący domknięciem jest nieuciekający: musi zostać wywołany przed zakończeniem funkcji. Należy oznaczyć go jako @escaping, jeśli może zostać zapisany i wywołany później.

Domknięcie nieuciekające

To domknięcie działa synchronicznie i przestaje istnieć po zakończeniu funkcji:

func run(_ work: () -> Void) {
    work()
}
run { print("done now") }  // "done now"

Dlaczego potrzebne jest @escaping

Przechowywanie domknięcia do późniejszego użycia wymaga oznaczenia @escaping:

var handlers: [() -> Void] = []
func register(_ handler: @escaping () -> Void) {
    handlers.append(handler)  // escapes the function
}
register { print("later") }
handlers[0]()  // "later"

Uciekające domknięcie i praca asynchroniczna

Procedury obsługi zakończenia są uciekające, ponieważ działają po zakończeniu funkcji:

func load(then completion: @escaping (String) -> Void) {
    // imagine async work
    completion("data")
}
load { result in print(result) }  // "data"

self musi być użyte jawnie

Wewnątrz uciekającego domknięcia podczas uzyskiwania dostępu do elementów instancji trzeba jawnie zapisać self. — przypomina to, że domknięcie może zatrzymywać self.

Jawne self w domknięciu uciekającym

Kompilator wymaga jawnego odwołania:

class Loader {
    var name = "L"
    func start(_ done: @escaping () -> Void) {
        let cb = { print(self.name); done() }
        cb()
    }
}
Loader().start { print("finished") }  // "L" then "finished"

Przechowywanie wielu wywołań zwrotnych

Uciekające domknięcia pozwalają tworzyć listy obserwatorów:

class Emitter {
    private var listeners: [(Int) -> Void] = []
    func on(_ l: @escaping (Int) -> Void) { listeners.append(l) }
    func fire(_ v: Int) { listeners.forEach { $0(v) } }
}
let e = Emitter()
e.on { print("got \($0)") }
e.fire(7)  // "got 7"

Zwracanie przechowywanego domknięcia

Domknięcia przechowywane we właściwościach są uciekające:

class Button {
    var action: (() -> Void)?
    func setAction(_ a: @escaping () -> Void) { action = a }
}
let b = Button()
b.setAction { print("tapped") }
b.action?()  // "tapped"

Opcjonalne domknięcia są uciekające

Parametr będący opcjonalnym domknięciem jest niejawnie uciekający (jest opakowany w Optional), więc można go przechowywać:

func maybe(_ f: (() -> Void)?) {
    f?()
}
maybe { print("ran") }  // "ran"

Uciekające domknięcia w tablicy zadań

Kolejka odroczonej pracy to klasyczny przypadek użycia domknięć uciekających — każde domknięcie jest przechowywane, a następnie uruchamiane później:

var tasks: [() -> Int] = []
func schedule(_ task: @escaping () -> Int) {
    tasks.append(task)
}
schedule { 1 + 1 }
schedule { 10 * 2 }
print(tasks.map { $0() })  // [2, 20]

Uwaga dotycząca wydajności

Domknięcia nieuciekające można optymalizować bardziej agresywnie (nie jest potrzebna alokacja na stercie). Jeśli to możliwe, należy pozostawiać domknięcia jako nieuciekające; należy używać uciekających tylko wtedy, gdy rzeczywiście są przechowywane lub odroczone.

func sum(_ xs: [Int], _ f: (Int) -> Int) -> Int {
    xs.reduce(0) { $0 + f($1) }   // non-escaping, fast
}
print(sum([1, 2, 3]) { $0 * $0 })  // 14

Szybkie sprawdzenie

Kiedy parametr będący domknięciem musi zostać oznaczony jako @escaping?

Podsumowanie

Poznał(a) Pan/Pani domknięcia uciekające:

  • Nieuciekające są domyślne; domknięcia są wykonywane przed zakończeniem funkcji
  • @escaping jest wymagane do przechowywania lub odraczania domknięcia
  • Uciekające domknięcia wymagają jawnego dostępu do self.
  • Parametry opcjonalnych domknięć są niejawnie uciekające; ze względu na wydajność należy preferować domknięcia nieuciekające

Dalej: listy przechwytywania i weak self.

Często zadawane pytania

Czy lekcja „Domknięcia uciekające” jest bezpłatna?

Tak — pełny tekst „Domknięcia uciekające” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Swift Academy, przejdź na CoddyKit PRO. Kurs Swift Academy zawiera 4 lekcji w sumie.

Co nauczysz się w „Domknięcia uciekające”?

Przechowywanie domknięć, które żyją dłużej niż ich funkcja. Ćwiczysz Swift Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.

Czy potrzebuję doświadczenia, aby zacząć Swift Academy?

Nie wymagamy żadnego doświadczenia. Swift Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 2 z 4.

Ile czasu zajmuje lekcja „Domknięcia uciekające”?

Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.

Czy mogę pisać i uruchamiać kod w tej lekcji Swift Academy?

Tak. Każda lekcja Swift Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.

Wszystkie lekcje w tym kursie

  1. Przechwytywanie wartości przez referencję
  2. Domknięcia uciekające
  3. Listy przechwytywania i weak self
  4. Autodomknięcia
← Powrót do Swift Academy