Я пытаюсь понять "Закрытие" Свифта более точно.
Но @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
Первый - для хранения замыкания, второй - для асинхронных рабочих целей.
Ниже приведены мои вопросы:
Во-первых, если doSomething
выполняется, то someFunctionWithEscapingClosure
будет выполняться с параметром замыкания, и это замыкание будет сохранено в массиве глобальных переменных.
Я думаю, что закрытие {self.x = 100}
Как self
в {self.x = 100}, которая сохраняется в глобальной переменной completionHandlers
может подключаться к instance
, что объект SomeClass
?
Во-вторых, я понимаю, что такая someFunctionWithEscapingClosure
такая.
Для хранения локальных переменных закрытия completionHandler
к глобальной переменной "completionHandlers we using
@escaping" ключевое слово!
без @escaping
слова @escaping
возвращает someFunctionWithEscapingClosure
, локальная переменная completionHandler
удалит из памяти
@escaping
держать это закрытие в памяти
Это правильно?
Наконец, мне просто интересно узнать о существовании этой грамматики.
Может быть, это очень элементарный вопрос.
Если мы хотим, чтобы какая-то функция выполнялась после какой-то конкретной функции. Почему бы нам просто не вызвать какую-либо функцию после вызова конкретной функции?
Каковы различия между использованием вышеупомянутого шаблона и использованием функции обратного вызова?