В Swift, в чем разница между (() -> ()) и @escaping () -> Void? - PullRequest
0 голосов
/ 29 апреля 2020

В чем разница между (() -> ()) и @escaping () -> Void?

func foo(_ completion: (() -> ()) { }

func boo(_ completion: @escaping () -> Void) { }

1 Ответ

0 голосов
/ 29 апреля 2020

Quick Excerpt


Экранирование замыканий
Говорят, что замыкание экранирует функцию, когда замыкание передается в качестве аргумента функции, но вызывается после функция возвращает. Когда вы объявляете функцию, которая принимает замыкание в качестве одного из своих параметров, вы можете написать @ escaping перед типом параметра, чтобы указать, что замыканию разрешено экранировать.

Один из способов, которым Закрытие может избежать, будучи сохраненным в переменной, которая определена вне функции. Например, многие функции, которые запускают асинхронную операцию, принимают аргумент замыкания в качестве обработчика завершения. Функция возвращается после запуска операции, но замыкание не вызывается до тех пор, пока операция не будет завершена - замыкание необходимо закрыть, чтобы вызвать его позже. Например:

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

Функция someFunctionWithEscapingClosure (_ :) принимает в качестве аргумента замыкание и добавляет его в массив, объявленный вне функции. Если вы не пометили параметр этой функции как @ escaping , вы получите ошибку во время компиляции. ”

“let alsoIncrementByTen = incrementByTen
alsoIncrementByTen()
// returns a value of 50

incrementByTen()
// returns a value of 60

Приведенный выше пример показывает, что вызов такжеInIncrementByTen является тем же как вызов incrementByTen. Поскольку оба они ссылаются на одно и то же замыкание, они оба увеличивают и возвращают одну и ту же промежуточную сумму.

Экранирование замыканий Говорят, что замыкание экранирует функцию, когда замыкание передается в качестве аргумента функции, но вызывается после возврата функции. Когда вы объявляете функцию, которая принимает замыкание в качестве одного из параметров, вы можете написать @ escaping перед типом параметра, чтобы указать, что замыканию разрешено экранировать.

Один из способов, которым Закрытие может избежать, будучи сохраненным в переменной, которая определена вне функции. Например, многие функции, которые запускают асинхронную операцию, принимают аргумент замыкания в качестве обработчика завершения. Функция возвращается после запуска операции, но замыкание не вызывается до тех пор, пока операция не будет завершена - замыкание необходимо закрыть, чтобы вызвать его позже. Например:

var completionHandlers: [() -> Void] = []
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}

Функция someFunctionWithEscapingClosure (_ :) принимает в качестве аргумента замыкание и добавляет его в массив, объявленный […] ”


Выдержка из: Apple В c. «Язык программирования Swift (Swift 5.2)». Apple Books. https://books.apple.com/us/book/the-swift-programming-language-swift-5-2/id881256329


Другими словами, @ экранирование замыканий требует использования self, если вы пытаетесь ссылаться на методы внутри текущего объекта. то есть Завершение замыканий SKActions является действительно хорошим примером этого.

И непересекающиеся замыкания не требуют использования self. Потому что они не использовались для ссылки на объект.

...