Singleton avec des propriétés à Swift 3


88

Dans le document Utilisation de Swift avec Cocoa et Objective-C d' Apple (mis à jour pour Swift 3), ils donnent l'exemple suivant du modèle Singleton:

class Singleton {
    static let sharedInstance: Singleton = {
        let instance = Singleton()

        // setup code

        return instance
    }()
}

Imaginons que ce singleton ait besoin de gérer un tableau variable de Strings. Comment / où déclarer cette propriété et m'assurer qu'elle est correctement initialisée dans un [String]tableau vide ?

Réponses:


236

Pour moi, c'est la meilleure façon de rendre init privé. Syntaxe Swift 3 \ 4 \ 5

// MARK: - Singleton

final class Singleton {

    // Can't init is singleton
    private init() { }

    // MARK: Shared Instance

    static let shared = Singleton()

    // MARK: Local Variable

    var emptyStringArray = [String]()

}

4
J'ai voté pour cette réponse, mais pour correspondre à la syntaxe Swift 3, "sharedInstance" devrait être changé en "shared".
B-Rad

1
À moins qu'il y ait une régression de Swift 2 à Swift 3, vous ne le faites pas
Thibaut Noah

1
Le type après partagé peut être omis, non? static let shared = Singleton()
chriswillow

1
@YannickSteph vous n'avez pas à écrire à la static let shared: Singleton = Singleton()place, vous pouvez simplement écrirestatic let shared = Singleton()
chriswillow

3
@RomanN Non, vous ne pouvez pas remplacer init car il n'hérite pas d'une classe. Si vous pouvez le faire, avec cet exemple final class Singleton: NSObject { private override init() { } }
YannSteph

59

Vous pouvez initialiser un tableau vide comme celui-ci.

class Singleton {

    //MARK: Shared Instance

    static let sharedInstance : Singleton = {
        let instance = Singleton(array: [])
        return instance
    }()

    //MARK: Local Variable

    var emptyStringArray : [String]

    //MARK: Init

    init( array : [String]) {
        emptyStringArray = array
    }
}

Ou si vous préférez une approche différente, celle-ci fera l'affaire.

class Singleton {

    //MARK: Shared Instance

    static let sharedInstance : Singleton = {
        let instance = Singleton()
        return instance
    }()

    //MARK: Local Variable

    var emptyStringArray : [String]? = nil

    //MARK: Init

    convenience init() {
        self.init(array : [])
    }

    //MARK: Init Array

    init( array : [String]) {
        emptyStringArray = array
    }
}

Cette méthode ne fonctionne-t-elle pas dans une extension? extension Cache { static let sharedInstance: Cache = { let instance = Cache() return instance }() }
Andy

1
Intéressant qu'Apple utilise class vardans iOS 10 pour les singletons (par exemple UIApplication). Leur mise en œuvre serait-elle la même que celle-ci?
jjatie

2
Je préfère les méthodes init singleton comme privateméthodes même pas internal. Cela empêche les autres d'utiliser l'initialiseur par défaut '()' pour cette classe.
Kumar C

1
@KumarC Vous avez raison, ne serait - il résoudre le problème si l' on ajoute un privatedans init.

@TikhonovAlexander Pouvez-vous nous apporter plus d'informations?
Dominique Vial

30

Selon la documentation d'Apple: dans Swift, vous pouvez simplement utiliser une propriété de type statique, qui est garantie d'être initialisée paresseusement une seule fois, même en cas d'accès simultané sur plusieurs threads .

class Singleton {

    // MARK: - Shared

    static let shared = Singleton()
}

Avec la méthode d'initialisation:

class Singleton {

    // MARK: - Shared

    static let shared = Singleton()

    // MARK: - Initializer

    private init() {
    }

}

3
pourquoi init () n'est pas privé?
XcodeNOOB

0

Toute initialisation serait effectuée dans une méthode init. Aucune différence ici entre un singleton et un non-singleton.


26
Un extrait de code supplémentaire qui répond directement à la question rendrait cette réponse plus utile.
Reda Lemeden
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.