Swift 1.2 a introduit un nouvel attribut : @noescape
. Cet attribut est très important car il permet de rendre le code plus sûr en évitant les cycles de rétention et donc les fuites mémoires. Voici ce que la documentation dit :
Le nouvel attribut
@noescape
ne peut être utilisé qu’en argument de fermeture des closures. Ceci indique que le paramètre peut être appeler que dans la closure (ou passé qu’en@noescape
dans un autre appel), ce qui signifie que le paramètre ne peut pas survivre en dehors de l’appel. Cet attribut permet des optimisations mineures sur les performances, mais désactive surtout l’usage duself
.
Nous allons commencer par analyser ces déclarations et les illustrer au travers de l’example suivant :
func swift(@noescape code:() -> String) -> String {
return "swift \(code())"
}
print(swift() { "tuto" })
// Affiche : swift tuto
Il peut aussi est capturer dans d’autres closure @noescape
:
func swift(@noescape code:() -> String) -> String {
return "swift \(tuto(code))"
}
func tuto(@noescape code:() -> String) -> String {
return code()
}
print(swift() { "tuto" })
// Affiche : swift tuto
Il est important de noter que les closures (et les fonctions) annotés avec l’attribut @noescape
peuvent seulement être passé comme paramètre @noescape
. Ceci veut dire :
- On ne peut exécuter le paramètre
@noescape
en mode asynchrone :
- On ne peut pas stocker le paramètre :
- On ne peut pas passer le paramètre dans d’autres closures non-
@noescape
:
Pour terminer, dans les prochaines versions l’attribut @noescape va aller encore plus loin. Ceci va permettre de créer des méthodes qui ressemblerons à des structures de contrôle car ils éviterons les effets de board. Dans de futur version, la librairie standard va adopter cet attribut dans des fonctions comme l’autoreleasepool
:
func autoreleasepool(@noescape code: () -> Void) {
pushAutoreleasePool()
code()
popAutoreleasePool()
}
Le meilleurs reste donc à venir. 🙂