Swift 3のプロパティを持つシングルトン


88

AppleのCocoaおよびObjective-CでのSwift使用(Swift 3用に更新)ドキュメントでは、シングルトンパターンの次の例が示されています。

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

        // setup code

        return instance
    }()
}

このシングルトンが文字列の可変配列を管理する必要があると想像してみましょう。どのように/どこでそのプロパティを宣言し、それが空の[String]配列に適切に初期化されるようにしますか?

回答:


236

私にとってはこれが最善の方法です。initを非公開にします。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
私はこの回答に賛成しましたが、Swift 3構文に一致させるには、「sharedInstance」を「shared」に変更する必要があります。
B-Rad、

1
swift 2からswift 3への回帰がない限り、そうではありません
thibaut noah

1
共有後の型は省略できますよね?static let shared = Singleton()
chriswillow 2017

1
@YannickSteph書く必要はありません。static let shared: Singleton = Singleton()代わりに書くことができますstatic let shared = Singleton()
chriswillow

3
@RomanNいいえ、クラスを継承しないため、initをオーバーライドすることはできません。それができる場合、この例では final class Singleton: NSObject { private override init() { } }
YannSteph

59

このように空の配列を初期化できます。

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
    }
}

または、別のアプローチを好む場合は、これで十分です。

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
    }
}

このメソッドは拡張機能では機能しませんか? extension Cache { static let sharedInstance: Cache = { let instance = Cache() return instance }() }
アンディ

1
Appleがclass varシングルトン(UIApplicationなど)のためにiOS 10で使用するのは興味深いことです。それらの実装はこれと同じでしょうか?
jjatie

2
私はprivateメソッドではなく、シングルトン初期化メソッドを好みinternalます。これにより、他のユーザーがこのクラスのデフォルトの '()'イニシャライザを使用できなくなります。
Kumar C

1
@KumarCあなたは私たちが追加した場合、それは問題を解決できないだろう、正しいですprivateinit

@TikhonovAlexanderもっと情報を持ってきてくれませんか?
Dominique Vial 2017年

30

アップルのドキュメントによると:Swiftでは、静的タイププロパティを使用できます。これは、複数のスレッドで同時にアクセスされた場合でも、1回だけ遅延初期化されることが保証されています

class Singleton {

    // MARK: - Shared

    static let shared = Singleton()
}

初期化メソッドを使用した場合:

class Singleton {

    // MARK: - Shared

    static let shared = Singleton()

    // MARK: - Initializer

    private init() {
    }

}

3
なぜinit()はプライベートではないのですか?
XcodeNOOB 2017

0

初期化はすべてinitメソッドで行われます。ここでは、シングルトンと非シングルトンの違いはありません。


26
質問に直接回答するコードスニペットを追加すると、この回答がさらに役立ちます。
Reda Lemeden
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.