Singleton dengan properti di Swift 3

88

Dalam dokumen Using Swift with Cocoa dan Objective-C Apple (diperbarui untuk Swift 3) mereka memberikan contoh pola Singleton berikut:

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

        // setup code

        return instance
    }()
}

Mari kita bayangkan bahwa singleton ini perlu mengelola array variabel Strings. Bagaimana / di mana saya akan mendeklarasikan properti itu dan memastikannya diinisialisasi dengan benar ke [String]array kosong ?

RobertJoseph
sumber

Jawaban:

236

Bagi saya ini adalah cara terbaik, menjadikan init pribadi. Sintaks 3 \ 4 \ 5 cepat

// 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]()

}
YannSteph
sumber
4
Saya memberi suara positif untuk jawaban ini, tetapi untuk mencocokkan sintaks Swift 3, "sharedInstance" harus diubah menjadi hanya "dibagikan".
B-Rad
1
Kecuali jika ada regresi dari swift 2 ke swift 3 yang tidak Anda lakukan
thibaut noah
1
Jenis setelah dibagikan dapat dihilangkan, bukan? static let shared = Singleton()
chriswillow
1
@YannickSteph Anda tidak perlu menulis, static let shared: Singleton = Singleton()Anda cukup menulisstatic let shared = Singleton()
chriswillow
3
@RomanN Tidak, Anda tidak dapat menimpa init karena init tidak mewarisi kelas. Jika Anda bisa melakukannya, dengan contoh ini final class Singleton: NSObject { private override init() { } }
YannSteph
59

Anda dapat menginisialisasi array kosong seperti ini.

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

Atau jika Anda lebih suka pendekatan yang berbeda, yang ini akan baik-baik saja.

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

sumber
Apakah metode ini tidak berfungsi di ekstensi? extension Cache { static let sharedInstance: Cache = { let instance = Cache() return instance }() }
Andrew
1
Menarik bahwa Apple menggunakan class variOS 10 untuk lajang (misalnya UIApplication). Apakah implementasinya akan sama dengan ini?
jjatie
2
Saya lebih suka metode init tunggal sebagai privatemetode bahkan bukan internal. Ini mencegah orang lain menggunakan penginisialisasi '()' default untuk kelas ini.
Kumar C
1
@KumarC Anda benar, tidak akan memecahkan masalah jika kita menambahkan privatedi init.
@TikhonovAlexander Bisakah Anda memberikan lebih banyak informasi?
Dominique Vial
0

Setiap inisialisasi akan dilakukan dengan metode init. Tidak ada perbedaan di sini antara tunggal dan bukan tunggal.

gnasher729
sumber
26
Potongan kode tambahan yang langsung menjawab pertanyaan akan membuat jawaban ini lebih berguna.
Reda Lemeden