Les autres réponses d'ici et de partout les interwebs sont assez grands, mais je sens que cette petite friandise doivent également être mentionnées:
La grande chose au sujet d' dispatch_once
était de savoir comment optimisé, il a été, essentiellement nixing le code après le premier run, d'une manière que j'ai peine à comprendre, mais je suis raisonnablement sûr que ce serait beaucoup plus rapide que la création et le contrôle d'un (vrai) global jeton.
Alors que le jeton chose qui pourrait raisonnablement être mis en œuvre de Swift, d'avoir à déclarer encore une autre stockées boolean n'est pas tout que de grands. Pour ne pas mentionner thread-dangereux. Comme la doc le dit, vous devez utiliser un "initialisées mondiale." Ouais, mais pourquoi encombrer la portée globale, droit?
Jusqu'à ce que quelqu'un me convainc une meilleure méthode, j'ai tendance à déclarer mes faire-une fois à l'intérieur fermeture à la portée que je vais utiliser, ou plus raisonnablement proches s'y rapportant, comme suit:
private lazy var foo: Void = {
// Do this once
}()
Fondamentalement, je suis en train de dire que "Quand j'ai lu cette, foo
devrait être le résultat de l'exécution de ce bloc." Il se comporte exactement de la même manière en tant que global let
constante, dans le droit de la portée. Et plus jolie. Puis je l'appellerais partout où je me tiens, par la lecture de quelque chose qui ne sera jamais utilisé autrement. J'aime Swift _
. Comme suit:
_ = foo
C'est vraiment cool de caprice a réellement été autour d'un certain temps, mais n'a pas vu beaucoup d'amour. Essentiellement, il quitte la variable seul au moment de l'exécution, comme une déplacée de fermeture, jusqu'à ce que quelque chose souhaite voir ses Void
résultat. En lecture, elle appelle la fermeture, la jette loin et maintient son résultat en foo
. Void
utilise pratiquement rien de ce mémoire, les lectures suivantes (c - _ = foo
) ne rien faire sur le CPU. (Ne pas citer de moi, quelqu'un veuillez vérifier l'assemblée pour être sûr!) Autant que vous le souhaitez, et Swift, fondamentalement, quitte à se soucier de ça après la première manche! Perdre que de vieilles dispatch_once_t
, et de garder beaucoup de votre code d'aussi jolie que lorsque vous l'avez ouvert le jour de Noël!
Mon seul problème est que vous pouvez définir foo
de quelque chose d'autre avant sa première lecture, puis votre code ne jamais être appelé! D'où le global let
constante, ce qui l'en empêche. Chose est, des constantes dans la classe étendue de ne pas bien jouer avec self
, donc pas de jouer avec les variables d'instance... Mais sérieusement, quand avez-vous mis quelque chose à l' Void
de toute façon??
Que, et vous avez besoin de spécifier le type de retour en tant que Void
ou ()
, sinon il va encore se plaindre self
. Qui da thunk?
Et lazy
, c'est juste pour faire de la variable différée, comme il se doit, donc, Swift ne pas l'exécuter directement sur init()
.
Assez snazzy, aussi longtemps que vous vous souvenez de ne pas écrire à! :P