web-dev-qa-db-fra.com

'dispatch_once_t' n'est pas disponible dans Swift: utilisez plutôt des globaux initialisés paresseusement

J'ai des problèmes avec dispatch_once_t Lors de la migration vers Swift 3.

Selon guide de migration d'Apple :

La fonction gratuite dispatch_once n'est plus disponible dans Swift. Dans Swift, vous pouvez utiliser des globales ou des propriétés statiques initialisés paresseusement et obtenir les mêmes garanties de sécurité des threads et d'appel unique que dispatch_once fourni. Exemple:

let myGlobal = { … global contains initialization in a call to a closure … }()

_ = myGlobal // using myGlobal will invoke the initialization code only the first time it is used.

J'ai donc voulu migrer ce code. C'était donc avant la migration:

class var sharedInstance: CarsConfigurator
{
    struct Static {
        static var instance: CarsConfigurator?
        static var token: dispatch_once_t = 0
    }

    dispatch_once(&Static.token) {
        Static.instance = CarsConfigurator()
    }

    return Static.instance!
}

Après la migration, en suivant les directives d'Apple (migration manuelle), le code ressemble à ceci:

class var sharedInstance: CarsConfigurator
{
    struct Static {
        static var instance: CarsConfigurator?
        static var token = {0}()
    }

    _ = Static.token

    return Static.instance!
}

Mais lorsque j'exécute cela, j'obtiens l'erreur suivante lors de l'accès à return Static.instance!:

erreur fatale: trouvé inopinément nul lors du déballage d'une valeur facultative

Je vois à partir de cette erreur que le membre instance est nil, mais pourquoi? Y a-t-il un problème avec ma migration?

23
Vladimir Nul

Ce code était trop verbeux même s'il était valide dans Swift 2. Dans Swift 3, Apple vous oblige à utiliser initialisation paresseuse par fermeture:

class CarsConfigurator {
    static let sharedInstance: CarsConfigurator = { CarsConfigurator() }()
}
19
Code Different