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.