@escaping
является заразительным для всех вызывающих методов, и компилятор определяет, когда вы должен включить его.
Рассмотрим следующий пример (который компилирует):
dispatchSometime({ print("Oh yeah") })
func dispatchSometime(_ block:()->()) {
dispatchNow(block)
}
func dispatchNow(_ block:()->()) {
block()
}
Этот модифицированный пример, однако, производит два ошибки типа non-escaping parameter may allow it to escape
:
dispatchSometime({ print("Oh yeah") })
func dispatchSometime(_ block:()->()) {
dispatchLater(block)
}
func dispatchLater(_ block:()->()) {
DispatchQueue.main.async(execute: block)
}
Отправка на главной означает потребности dispatchLater
метод @escaping
, и как только вы добавили это, метод dispatchSometime
также требует: @escaping
для примера для компиляции.
dispatchSometime({ print("Oh yeah") })
func dispatchSometime(_ block: @escaping()->()) {
dispatchLater(block)
}
func dispatchLater(_ block: @escaping()->()) {
DispatchQueue.main.async(execute: block)
}
Однако отнимать просто:
- Продолжайте добавлять
@escaping
вверх по цепочке вызовов, пока компилятор не перестанет жаловаться.
- Ключевое слово ничего не меняет: это предупреждение, которое говорит, по существу, «будьте осторожны с использованием
weak
с захваченными переменными, поскольку они могут сохраняться вместе с самим блоком».
Последствия
Действительно весело случае это, где вы должны настроить несколько способов включить @escaping
ключевое слово, которое получает компилятор прекратить жаловаться. Однако, если эти методы фактически соответствуют протоколу, методы этого протокола должны также получить ключевое слово @escaping
, которое также заражает все другие протокольные согласования. Весело!
См. Это [Закрытие использования параметра без экранирования может позволить ему уйти] (https://stackoverflow.com/q/38990882/6521116) –