静态计算变量不止一次被实例化

时间:2016-05-18 22:15:40

标签: ios swift static nsdate nsdateformatter

我有一个日期格式化程序我试图在UITableViewCell子类中创建一个单例,所以我创建了一个这样的计算属性:

private static var dateFormatter: NSDateFormatter {
    print("here here")
    let formatter = NSDateFormatter()
    formatter.dateFormat = "EEEE h a"
    return formatter
}

问题是我不止一次看到print语句,这意味着它不止一次被创建。我已经找到了其他方法(比如加入外部课程或类课程),但我很想知道这里发生了什么。有什么想法吗?

4 个答案:

答案 0 :(得分:15)

您的代码段相当于只获取属性,基本上与以下内容相同:

private static var dateFormatter: NSDateFormatter {
    get {
        print("here here")
        let formatter = NSDateFormatter()
        formatter.dateFormat = "EEEE h a"
        return formatter
    }
}

如果你只想运行一次,你应该像定义一个惰性属性一样定义它:

private static var dateFormatter: NSDateFormatter = {
    print("here here")
    let formatter = NSDateFormatter()
    formatter.dateFormat = "EEEE h a"
    return formatter
}()

答案 1 :(得分:2)

在尝试找出Swift中包含=()的静态计算属性与不包含static var foo: String { print("computing foo") return "foo" } static var bar: String = { print("computing bar") return "bar" }() for _ in 1...3 { print(Class.foo) print(Class.bar) } 的静态计算属性之间的差异时,我花了一些时间才找到这个问题。 @dan做了很好的工作,解释了应该做些什么来确保静态属性只计算一次,但在我自己的实验中,我想出了以下示例,帮助我可视化两种用途之间的差异。

computing foo
foo
computing bar
bar
computing foo
foo
bar
computing foo
foo
bar

最终结果是:

foo

bar具有静态属性的好处,包括与类型而不是特定实例的关联以及无法被子类覆盖。然而,event.keyCode更进一步确保财产只计算一次。

答案 2 :(得分:1)

静态属性可以是computed,也可以是lazy,具体取决于您如何写出来。

-computed意味着它们的值将在每次被调用时重新计算:

private static var dateFormatter: NSDateFormatter {
    print("here here") // prints each time dateFormatter its called
    let formatter = NSDateFormatter()
    formatter.dateFormat = "EEEE h a"
    return formatter
}

-lazy意味着它们的值将被计算一次,并且仅在首次调用它们时被计算:

private static var dateFormatter: NSDateFormatter = {
    print("here here") // prints only one time, when called first time
    let formatter = NSDateFormatter()
    formatter.dateFormat = "EEEE h a"
    return formatter
}()

答案 3 :(得分:0)

您的静态var不是单例,它只是一个创建并返回日期格式化程序实例的类方法。

检查如何创建真正的sungleton的这些答案:Using a dispatch_once singleton model in Swift