Próbuję dokładniej zrozumieć „Zamknięcie” Swifta.
Ale @escaping
i Completion Handler
są zbyt trudne do zrozumienia
Przeszukałem wiele ogłoszeń Swift i oficjalnych dokumentów, ale czułem, że to wciąż za mało.
To jest przykład kodu oficjalnych dokumentów
var completionHandlers: [()->Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping ()->Void){
completionHandlers.append(completionHandler)
}
func someFunctionWithNoneescapingClosure(closure: ()->Void){
closure()
}
class SomeClass{
var x:Int = 10
func doSomething(){
someFunctionWithEscapingClosure {
self.x = 100
//not excute yet
}
someFunctionWithNoneescapingClosure {
x = 200
}
}
}
let instance = SomeClass()
instance.doSomething()
print(instance.x)
completionHandlers.first?()
print(instance.x)
Słyszałem, że są dwa sposoby i powody używania @escaping
Pierwszy służy do przechowywania zamknięcia, a drugi do celów operacyjnych Async.
Oto moje pytania :
Po pierwsze, jeśli doSomething
Wykonuje wtedy someFunctionWithEscapingClosure
będzie wykonanie z parametrem zamknięcia i zamknięcie zostanie zapisany w globalnej tablicy zmiennych.
Myślę, że zamknięcie to {self.x = 100}
Jak self
w {self.x = 100} ta zapisana w zmiennej globalnej completionHandlers
może połączyć się z instance
tym obiektem SomeClass
?
Po drugie, rozumiem w someFunctionWithEscapingClosure
ten sposób.
Aby przechowywać lokalne zamknięcie zmiennej completionHandler
w globalnym we using
słowie kluczowym „completeHandlers @ escaping”!
bez zwracania @escaping
słów kluczowych someFunctionWithEscapingClosure
zmienna lokalna completionHandler
zostanie usunięta z pamięci
@escaping
to zachować to zamknięcie w pamięci
Czy to jest poprawne?
Na koniec po prostu zastanawiam się nad istnieniem tej gramatyki.
Może to bardzo podstawowe pytanie.
Jeśli chcemy, aby jakaś funkcja była wykonywana po określonej funkcji. Dlaczego po prostu nie wywołamy jakiejś funkcji po wywołaniu określonej funkcji?
Jakie są różnice między użyciem powyższego wzorca a użyciem funkcji ucieczki zwrotnej?