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.