Уточнение:
Для понимания ситуации было бы полезно реализовать следующий код:
typealias completion = () -> ()
enum CompletionHandler {
case success
case failure
static var handler: completion {
get { return { } }
set { }
}
}
func doSomething(handlerParameter: completion) {
let chObject = CompletionHandler.handler = handlerParameter
}
На первый взгляд этот код кажется законным, но это не так! вы получите сообщение об ошибке времени компиляции:
ошибка: присвоение неоткрывающего параметра handlerParameter закрытию @escaping
let chObject = CompletionHandler.handler = handlerParameter
с примечанием, что:
примечание: параметр 'handlerParameter' неявно не экранирующий func doSomething (handlerParameter: Завершение) {
Это почему? предполагается, что фрагмент кода не имеет ничего общего с _2 _...
Фактически, поскольку был выпущен Swift 3, замыкание будет «экранировано», если оно объявлено в enum, struct или class по умолчанию.
Для справки сообщаем об ошибках, связанных с этой проблемой:
Хотя они могут не на 100% относиться к этому делу, комментарии правопреемника четко описывают дело:
Первый комментарий:
Фактическая проблема здесь в том, что необязательные закрытия прямо сейчас неявно @escaping.
Второй комментарий:
К сожалению, это относится к Swift 3. Вот семантика экранирования в Swift 3:
1) Замыкания в позиции параметра функции по умолчанию не экранируются.
2) Все остальные закрытия ускользают
Таким образом, все замыкания аргументов универсального типа, такие как Array и Optional, экранируются.
Очевидно, Optional
- это перечисление.
Также, как упоминалось выше, такое же поведение применимо к классам и структурам:
Дело класса:
typealias completion = () -> ()
class CompletionHandler {
var handler: () -> ()
init(handler: () -> ()) {
self.handler = handler
}
}
func doSomething(handlerParameter: completion) {
let chObject = CompletionHandler(handler: handlerParameter)
}
Случай структуры:
typealias completion = () -> ()
struct CompletionHandler {
var handler: completion
}
func doSomething(handlerParameter: completion) {
let chObject = CompletionHandler(handler: handlerParameter)
}
Два приведенных выше фрагмента кода приведут к одному и тому же результату (ошибка времени компиляции).
Для исправления ситуации вам необходимо разрешить подпись функции:
func doSomething( handlerParameter: @escaping completion)
Вернемся к основному вопросу:
Поскольку вы ожидаете, что вы должны позволить completion:(()->())?
быть экранированным, это будет сделано автоматически - как описано выше-.
person
Ahmad F
schedule
21.11.2017