Comment puis-je exécuter du code une seule fois dans Swift?
Les réponses que j'ai vu jusqu'à présent (UnDeuxTrois) vous recommandons d'utiliser le PGCD de dispatch_once
ainsi:
var token: dispatch_once_t = 0
func test() {
dispatch_once(&token) {
print("This is printed only on the first call to test()")
}
print("This is printed for each call to test()")
}
test()
De sortie:
This is printed only on the first call to test()
This is printed for each call to test()
Mais attendez une minute. token
est une variable, donc j'ai pu facilement le faire:
var token: dispatch_once_t = 0
func test() {
dispatch_once(&token) {
print("This is printed only on the first call to test()")
}
print("This is printed for each call to test()")
}
test()
token = 0
test()
De sortie:
This is printed only on the first call to test()
This is printed for each call to test()
This is printed only on the first call to test()
This is printed for each call to test()
Donc dispatch_once
est d'aucune utilité si nous je peux changer la valeur de token
! Et en tournant token
dans une constante n'est pas simple, car il doit de type UnsafeMutablePointer<dispatch_once_t>
.
Donc devrions-nous renoncer à dispatch_once
dans Swift? Est-il un moyen plus sûr pour exécuter le code qu'une fois?
source d'informationauteur Eric
Vous devez vous connecter pour publier un commentaire.
Propriétés statiques initialisé par une fermeture sont exécutés paresseusement et plus d'une fois, si cela s'imprime qu'une seule fois, en dépit d'être appelé deux fois:
Exemple:
Un homme est allé chez le médecin, et dit: "Docteur, ça fait mal quand je le timbre sur mon pied". Le médecin a répondu: "cessez Donc de le faire".
Si vous avez délibérément modifier votre envoi jeton, alors oui - vous serez en mesure d'exécuter le code deux fois. Mais si vous travaillez autour de la logique conçu pour empêcher l'exécution de plusieurs dans tout façon, vous serez en mesure de le faire.
dispatch_once
est encore la meilleure méthode pour assurer le code n'est exécuté qu'une fois, comme il s'occupe de toutes les (très) complexe coin de cas autour de l'initialisation et des conditions de course qu'un simple booléen ne couvre pas.Si vous avez peur que quelqu'un pourrait accidentellement réinitialiser le jeton, vous pouvez l'envelopper dans une méthode et de le rendre aussi évident qu'il peut être quelles sont les conséquences. Quelque chose comme ce qui suit sera portée le jeton à la méthode, et empêcher quiconque de le modifier sans effort sérieux:
Je pense que la meilleure approche est de construire des ressources paresseusement en tant que de besoin. Swift permet cela facilement.
Il y a plusieurs options. Comme déjà mentionné, vous pouvez initialiser une propriété statique à l'intérieur d'un type à l'aide d'une fermeture.
Cependant, l'option la plus simple est de définir une variable globale (ou constante) et de l'initialiser avec une fermeture référence à cette variable n'importe où le code d'initialisation est nécessaire d'avoir arrivé une fois:
Une autre option consiste à envelopper le type au sein d'une fonction de sorte qu'il lit mieux lors de l'appel. Par exemple:
Vous pouvez faire des variations sur ce que nécessaire. Par exemple, au lieu d'utiliser le type interne à la fonction, vous pouvez utiliser un mondial privé et interne ou de la fonction publique, en tant que de besoin.
Cependant, je pense que la meilleure approche consiste simplement à déterminer quelles ressources vous avez besoin d'initialiser et créer paresseusement de manière globale ou statique de propriétés.