@noescape attribut dans Swift 1.2
Il y a un nouvel attribut dans Swift 1.2 avec la fermeture des paramètres dans les fonctions, et comme le dit la documentation:
Cela indique que le
paramètre n'est jamais appelé (ou passé comme une
@
noescape paramètre dans l'appel), ce qui signifie qu'il ne peut pas
durer plus longtemps que la durée de l'appel.
Dans ma compréhension, avant cela, nous pourrions utiliser [weak self]
pour ne pas laisser la fermeture d'avoir une référence forte, par exemple de sa classe, et l'auto pourrait être nul ou de l'instance lorsque la fermeture est exécuté, mais maintenant, @noescape
signifie que la fermeture ne sera jamais exécutée si la classe est deinitalized. Suis-je comprends bien?
Et si je suis correct, pourquoi voudrais-je utiliser un @noescape
fermeture insted d'une fonction régulière, quand ils se comporte très similaires?
Vous devez vous connecter pour publier un commentaire.
@noescape
peut être utilisée comme ceci:Ajoutant
@noescape
garantit que la fermeture ne sera pas stocké quelque part, utilisés à une date ultérieure, ou utilisés de manière asynchrone.De l'appelant point de vue, il n'y a pas besoin de se soucier de la durée de vie de la capture de variables, car ils sont utilisés au sein de la fonction appelée ou pas du tout. Et en bonus, on peut utiliser un implicite
self
, nous sauver de taperself.
.Aussi, du compilateur, du point de vue (comme indiqué dans notes de version):
@noescape
garantit que la fermeture ne sera pas... utilisé en mode asynchrone". Ce qui signifie que vous ne pouvez pas l'utiliser avec le code de mise en réseau que les feux asynchrone.Une façon de penser, c'est que CHAQUE variable à l'intérieur de la @noescape bloc n'a pas besoin d'être Fort (et pas seulement le soi).
Il y a aussi des optimisations possibles, car une fois qu'une variable est allouée qu'ensuite enveloppé dans un bloc, il ne peut pas être normalement libéré à la fin de la fonction. Donc, il doit être alloué sur le Tas et l'utilisation de l'ARC à déconstruire. En Objective-C, vous devez utiliser la fonction "__bloc" mot-clé pour s'assurer que la variable est créée dans un bloc de manière conviviale. Swift détecte automatiquement si le mot clé n'est pas nécessaire, mais le coût est le même.
Si les variables sont transmises à un @nosecape bloc, qu'ils peuvent être variables de pile, et n'ont pas besoin de l'ARC pour désallouer.
Les variables de maintenant n'ont même pas besoin d'être zéro de référencement de faible variables (qui sont plus chers que les dangereux pointeurs), car ils seront assurés d'être "vivant" pour la durée de vie du bloc.
Tout cela est plus rapide et plus un code optimal. Et réduit les frais généraux pour l'utilisation de @autoclosure blocs (qui sont très utiles).
(En référence à Michael Gray réponse ci-dessus.)
Ne sais pas si cela est documenté pour Swift, ou si même la Swift compilateur prend en profiter pleinement. Mais c'est la norme conception du compilateur d'allouer du stockage d'une instance sur la pile si le compilateur sait que la fonction appelée ne tentera pas de stocker un pointeur vers l'instance dans le tas, et d'émettre une erreur de compilation si la fonction tente de le faire.
Ceci est particulièrement avantageux lors du passage de la non-valeur scalaire types (type enum, struct, fermetures) parce que la copie est potentiellement beaucoup plus cher que de simplement en passant un pointeur sur la pile. L'attribution de l'instance est aussi nettement moins cher (une instruction contre l'appel de malloc()). Donc c'est un double-gagnant si le compilateur peut faire cette optimisation.
Encore une fois, si une version de la Swift compilateur ne fait devra être déclaré par l'équipe Swift, ou vous devriez lire le code source à l'open-source. À partir de la citation ci-dessus à propos de "mineur optimisation", il semble que ce soit il ne l'est pas, ou l'équipe Swift estime qu'il est "mineur". Je pense qu'il serait une optimisation importante.
Sans doute l'attribut n'est là que pour (au moins dans l'avenir), le compilateur sera en mesure d'effectuer cette optimisation.