在Swift 3中具有属性的Singleton


88

在苹果公司的《将Swift与Cocoa和Objective-C结合使用》(针对Swift 3更新)中,他们给出了Singleton模式的以下示例:

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

        // setup code

        return instance
    }()
}

让我们想象一下,这个单例需要管理一个可变的String数组。我将如何/在何处声明该属性,并确保将其正确初始化为空[String]数组?

Answers:


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
除非有从迅速2到迅速3的回归,否则您不会
thibaut noah 17-4-21

1
共享后的类型可以省略,对吗?static let shared = Singleton()
chriswillow

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在iOS 10中用于单例(例如UIApplication)的有趣。它们的实现会与此相同吗?
jjatie

2
我更喜欢单例初始化方法而private不是方法internal。这样可以防止其他人对该类使用默认的'()'初始化程序。
库马尔C

1
@KumarC您是正确的,如果我们添加privatein ,它将不能解决问题init

@TikhonovAlexander您能带来更多信息吗?
Dominique Vial


0

任何初始化都可以通过init方法完成。单例和非单例在这里没有区别。


26
直接回答问题的其他代码段将使此答案更有帮助。
Reda Lemeden
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.