静态计算变量被多次实例化
Static computed variable gets instantiated more than once
我有一个日期格式化程序,我试图在 UITableViewCell
子 class 中创建一个单例,所以我创建了一个计算 属性 ,如下所示:
private static var dateFormatter: NSDateFormatter {
print("here here")
let formatter = NSDateFormatter()
formatter.dateFormat = "EEEE h a"
return formatter
}
问题是我不止一次看到打印语句,这意味着它被创建了不止一次。我找到了其他方法来执行此操作(例如放入外部 class 或 class 方法),但我很想了解这里发生了什么。有什么想法吗?
您的静态变量不是单例,它只是一个 class 创建和 returns 日期格式化程序实例的方法。
检查这些关于如何创建真正的单胞胎的答案:Using a dispatch_once singleton model in Swift
你的代码片段相当于一个 get-only 属性,基本上它是一样的:
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
}()
当我试图弄清楚 Swift 中包含 =
和 ()
的静态计算 属性 之间的区别时,我花了一段时间才找到这个问题和一个没有。 @dan 很好地解释了应该如何确保静态 属性 只计算一次,但在我自己的实验中,我想出了以下示例,它帮助我形象化了两种用途之间的差异。
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)
}
最终结果是:
computing foo
foo
computing bar
bar
computing foo
foo
bar
computing foo
foo
bar
foo
具有静态 属性 的优点,包括与类型关联而不是特定实例,并且不能被子类覆盖。然而,bar
更进一步,确保 属性 仅计算一次。
静态属性可以是 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
}()
我有一个日期格式化程序,我试图在 UITableViewCell
子 class 中创建一个单例,所以我创建了一个计算 属性 ,如下所示:
private static var dateFormatter: NSDateFormatter {
print("here here")
let formatter = NSDateFormatter()
formatter.dateFormat = "EEEE h a"
return formatter
}
问题是我不止一次看到打印语句,这意味着它被创建了不止一次。我找到了其他方法来执行此操作(例如放入外部 class 或 class 方法),但我很想了解这里发生了什么。有什么想法吗?
您的静态变量不是单例,它只是一个 class 创建和 returns 日期格式化程序实例的方法。
检查这些关于如何创建真正的单胞胎的答案:Using a dispatch_once singleton model in Swift
你的代码片段相当于一个 get-only 属性,基本上它是一样的:
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
}()
当我试图弄清楚 Swift 中包含 =
和 ()
的静态计算 属性 之间的区别时,我花了一段时间才找到这个问题和一个没有。 @dan 很好地解释了应该如何确保静态 属性 只计算一次,但在我自己的实验中,我想出了以下示例,它帮助我形象化了两种用途之间的差异。
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)
}
最终结果是:
computing foo
foo
computing bar
bar
computing foo
foo
bar
computing foo
foo
bar
foo
具有静态 属性 的优点,包括与类型关联而不是特定实例,并且不能被子类覆盖。然而,bar
更进一步,确保 属性 仅计算一次。
静态属性可以是 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
}()