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 }) // 14Szybkie 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
@escapingjest 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
- Przechwytywanie wartości przez referencję
- Domknięcia uciekające
- Listy przechwytywania i weak self
- Autodomknięcia