Donné:
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-t-il un moyen de rendre le completion
paramètre (et action
) de type Action?
et de le conserver également @escaping
?
Changer le type donne l'erreur suivante:
L'attribut @escaping s'applique uniquement aux types de fonction
En supprimant l' @escaping
attribut, le code se compile et s'exécute, mais ne semble pas être correct car la completion
fermeture échappe à la portée de la fonction.
@escaping
attribut, le code se compile et s'exécute" - C'est parce que, comme décrit dans SR-2444 ,Action?
est, par défaut, échappement. Ainsi, la suppression@escaping
lors de l'utilisation de la fermeture optionnelle accomplit ce dont vous avez besoin.Réponses:
Il existe un rapport SR-2552 qui
@escaping
ne reconnaît pas l'alias de type de fonction. c'est pourquoi l'erreur@escaping attribute only applies to function types
. vous pouvez contourner le problème en développant le type de fonction dans la signature de fonction:MODIFIER 1 ::
J'étais en fait sous une version bêta de xcode 8 où le bogue SR-2552 n'était pas encore résolu. correction de ce bogue, en a introduit un nouveau (celui auquel vous êtes confronté) qui est toujours ouvert. voir SR-2444 .
La solution de contournement indiquée par @Michael Ilseman comme une solution temporaire consiste à supprimer l'
@escaping
attribut du type de fonction facultatif, qui garde la fonction en échappement .MODIFIER 2 ::
Le SR-2444 a été fermé en indiquant explicitement que la fermeture des postes de paramètres ne sont pas échapper et doivent être marqués les avec
@escaping
pour les faire échapper, mais les paramètres facultatifs sont échappaient implicitement, car((Int)->())?
est un synonymes deOptional<(Int)->()>
, fermetures en option fuient.la source
@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.
Pouvez-vous expliquer cela davantage? La sémantique par défaut dans swift 3 est sans échappement. Bien qu'il se compile sans @escaping, j'ai peur que cela pose des problèmes en étant traité comme non-échappant. N'est-ce pas vrai?@autoclosure
? On obtient la même erreur là-bas ...de: liste de diffusion swift-users
Le paramètre de fonction facultatif est donc @escaping par défaut.
@noeascape s'applique uniquement au paramètre de fonction par défaut.
la source
(()->Void)?
que vous avezOptional<()->Void>
et pourOptional
conserver la propriété, il ne devrait accepter que des@escaping
fonctions. Je troisième que cela devrait être la réponse acceptée. Je vous remercie.J'ai rencontré un problème similaire parce que mélanger
@escaping
et non@escaping
est très déroutant, surtout si vous devez passer les fermetures.J'ai fini par attribuer une valeur par défaut sans opération au paramètre de fermeture via
= { _ in }
, ce qui, à mon avis, a plus de sens:la source
Je l'ai fait fonctionner dans Swift 3 sans aucun avertissement uniquement de cette façon:
la source
La chose importante à comprendre dans l'exemple est que si vous changez
Action
àAction?
la fermeture est s'échapper. Alors, faisons ce que vous proposez:OK, maintenant nous allons appeler
doStuff
:Eh bien, cette exigence ne se pose que pour échapper aux fermetures. La fermeture s'échappe donc. C'est pourquoi vous ne marquez pas qu'il s'échappe - il s'échappe déjà.
la source