Я намагаюся зрозуміти «закриття» Свіфта точніше.
Але @escaping
і Completion Handler
їх занадто важко зрозуміти
Я шукав багато поштових повідомлень Свіфта та офіційні документи, але відчув, що цього ще недостатньо.
Це приклад коду офіційних документів
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)
Я чув, що існують два способи та причини @escaping
Перший - для зберігання блокування, другий - для операційних цілей Async.
Наступні мої запитання :
По-перше, якщо doSomething
Executes, то someFunctionWithEscapingClosure
буде виконано параметр закриття, і закриття буде збережено у глобальному масиві змінних.
Я думаю, що закриття - {self.x = 100}
Як self
у {self.x = 100}, що зберігається в глобальній змінній, completionHandlers
можна підключитися до instance
цього об’єкта SomeClass
?
По-друге, я так розумію someFunctionWithEscapingClosure
.
Для зберігання локального закриття змінної completionHandler
до глобальної змінної we using
ключового слова "завершенняHandlers @ escape"!
без повернення @escaping
ключового слова someFunctionWithEscapingClosure
локальна змінна completionHandler
буде видалена з пам'яті
@escaping
це зберегти це закриття в пам'яті
Чи це правильно?
Нарешті, мені просто цікаво існування цієї граматики.
Можливо, це дуже елементарне питання.
Якщо ми хочемо, щоб якась функція виконувалася після якоїсь конкретної функції. Чому ми не викликаємо якусь функцію після виклику певної функції?
Які відмінності між використанням вищезазначеного шаблону та використанням функцією зворотного виклику, що виходить?