Dado:
typealias Action = () -> ()
var action: Action = { }
func doStuff(stuff: String, completion: @escaping Action) {
print(stuff)
action = completion
completion()
}
func doStuffAgain() {
print("again")
action()
}
doStuff(stuff: "do stuff") {
print("swift 3!")
}
doStuffAgain()
Existe alguma maneira de fazer o completion
parâmetro (e action
) do tipo Action?
e também manter @escaping
?
Alterar o tipo gera o seguinte erro:
O atributo @escaping se aplica apenas a tipos de função
Removendo o @escaping
atributo, o código compila e executa, mas não parece estar correto, pois o completion
fechamento está escapando do escopo da função.
@escaping
atributo, o código compila e executa" - Isso porque, conforme descrito no SR-2444 ,Action?
está, por padrão, escapando. Portanto, remover@escaping
ao usar o fechamento opcional realiza o que você precisa.Respostas:
Há um relatório SR-2552 que
@escaping
não reconhece o alias do tipo de função. é por isso que o erro@escaping attribute only applies to function types
. você pode solucionar esse problema expandindo o tipo de função na assinatura da função:EDIT 1 :
Na verdade, eu estava na versão beta do xcode 8, onde o bug SR-2552 ainda não havia sido resolvido. corrigindo esse erro, introduziu um novo (o que você está enfrentando) que ainda está aberto. veja SR-2444 .
A solução alternativa @Michael Ilseman apontada como uma solução temporária é remover o
@escaping
atributo do tipo de função opcional, que mantém a função como escapada .EDIT 2 :
O SR-2444 foi fechado informando explicitamente que os fechamentos nas posições dos parâmetros não estão escapando e precisa que eles sejam marcados com
@escaping
para fazê-los escapar, mas os parâmetros opcionais estão implicitamente escapando, já que((Int)->())?
é um sinônimo deOptional<(Int)->()>
, os fechamentos opcionais estão escapando.fonte
@escaping may only be applied to parameters of function type func doStuff(stuff: String, completion: (@escaping ()->())?) {
a temporary solution is remove the @escaping attribute from optional function type, that keep the function as escaping.
Você pode explicar isso mais? A semântica padrão no swift 3 é sem escape. Embora seja compilado sem @ escape, receio que causará problemas ao ser tratado como não escapante. Isso não é verdade?@autoclosure
? É possível obter o mesmo erro ...de: lista de discussão swift-users
Portanto, o parâmetro de função opcional é @escaping por padrão.
O @noeascape se aplica apenas ao parâmetro function por padrão.
fonte
(()->Void)?
é o mesmo que dizer que você possuiOptional<()->Void>
e, paraOptional
manter a propriedade, ele deve aceitar apenas@escaping
funções. Terceiro, essa deve ser a resposta aceita. Obrigado.Eu tive um problema semelhante porque misturar
@escaping
e não@escaping
é muito confuso, especialmente se você precisar passar pelos fechamentos.Acabei atribuindo um valor padrão no-op ao parâmetro de fechamento via
= { _ in }
, o que acho que faz mais sentido:fonte
Eu consegui trabalhar no Swift 3 sem nenhum aviso apenas desta maneira:
fonte
O importante a entender no exemplo é que, se você mudar
Action
paraAction?
o fechamento, está escapando. Então, vamos fazer o que você propõe:Ok, agora vamos ligar
doStuff
:Bem, esse requisito só surge para escapar de fechamentos. Então o fechamento está escapando. É por isso que você não marca como escapando - já está escapando.
fonte