Swift 3 özellikli Singleton


88

Apple'ın Swift'i Cocoa ve Objective-C ile Kullanması belgesinde (Swift 3 için güncellendi), aşağıdaki Singleton kalıbı örneğini veriyorlar:

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

        // setup code

        return instance
    }()
}

Bu singleton'un değişken bir String dizisini yönetmesi gerektiğini düşünelim. Bu özelliği nasıl / nerede bildiririm ve boş bir [String]diziye düzgün şekilde başlatılmasını sağlar ?

Yanıtlar:


236

Benim için en iyi yol bu, initi özel yapmak. Hızlı 3 \ 4 \ 5 sözdizimi

// 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
Bu yanıta oy verdim, ancak Swift 3 sözdizimine uyması için "sharedInstance" yalnızca "paylaşılan" olarak değiştirilmelidir.
B-Rad

1
Hızlı 2'den hızlı 3'e bir gerileme olmadıkça
yapmazsınız

1
Paylaşıldıktan sonraki tür ihmal edilebilir, değil mi? static let shared = Singleton()
chriswillow

1
Eğer yazmak zorunda değilsiniz @YannickSteph static let shared: Singleton = Singleton()yerine sadece yazabilirsinizstatic let shared = Singleton()
chriswillow

3
@RomanN Hayır, bir sınıfı miras almadığı için init'i geçersiz kılamazsınız. Bunu yapabilirseniz, bu örnekle final class Singleton: NSObject { private override init() { } }
YannSteph

59

Bunun gibi boş bir dizi başlatabilirsiniz.

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

Veya farklı bir yaklaşımı tercih ederseniz, bu iyi olacaktır.

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

Bu yöntem bir uzantıda çalışmıyor mu? extension Cache { static let sharedInstance: Cache = { let instance = Cache() return instance }() }
Andrew

1
Apple'ın class variOS 10'da singleton'lar için kullanması ilginç (örn. UIApplication). Uygulamaları bununla aynı mı olur?
jjatie

2
Tekil init yöntemlerini yöntemler olarak tercih ediyorum privatebile internal. Bu, başkalarının bu sınıf için varsayılan '()' başlatıcısını kullanmasını engeller.
Kumar C

1
@KumarC Doğru söylüyorsunuz, bir privatein eklersek sorunu çözmez init.

@TikhonovAlexander Daha fazla bilgi getirebilir misiniz?
Dominique Vial

30

Apple'ın belgelerine göre: Swift'de, aynı anda birden fazla iş parçacığı üzerinden erişildiğinde bile yalnızca bir kez tembel olarak başlatılması garanti edilen bir statik tür özelliğini kullanabilirsiniz .

class Singleton {

    // MARK: - Shared

    static let shared = Singleton()
}

Başlatma yöntemiyle:

class Singleton {

    // MARK: - Shared

    static let shared = Singleton()

    // MARK: - Initializer

    private init() {
    }

}

3
init () neden özel değil?
XcodeNOOB

0

Herhangi bir başlatma, bir başlatma yönteminde yapılacaktır. Burada tekli ve tek olmayan arasında fark yok.


26
Soruyu doğrudan yanıtlayan ek bir kod parçası, bu yanıtı daha yararlı hale getirecektir.
Reda Lemeden
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.