如何在 Swift class 扩展中创建 'static'?
How does one create a 'static' in a Swift class extension?
在这里的几个地方,有人建议在 NSDate
的扩展中使用计算的 属性 可能是通过 [=15= 获取日期的字符串版本的好方法],像这样:
extension NSDate {
public var UTC : String {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
formatter.timeZone = NSTimeZone(abbreviation: "UTC")
return formatter.stringFromDate(self)
}
}
然而,分配一个 NSDateFormatter
是昂贵的,建议它们被创建一次并缓存。每次格式化日期时,上面的代码都会创建 NSDateFormatter
,我想知道是否有一种方法可以在扩展中创建 NSDateFormatter
once 以供重用?
显然,我可以在扩展之外创建它一次,但这似乎破坏了表征 类.
的封装
我想起了:https://xkcd.com/1179/ !!
您可以将静态成员添加到 class 扩展,就像在 classes 上一样。使用时需要在静态成员名称前加上 class 前缀,例如NSDate.dateFormatterUTC
,即使您在同一个 class.
中使用它
这个有效:
extension NSDate {
private static let dateFormatterUTC: NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
formatter.timeZone = NSTimeZone(abbreviation: "UTC")
return formatter
}()
public var UTC : String {
return NSDate.dateFormatterUTC.stringFromDate(self)
}
}
仅仅使用私有常量也不是世界上最糟糕的事情:
private let dateFormatterUTC: NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
formatter.timeZone = NSTimeZone(abbreviation: "UTC")
return formatter
}()
extension NSDate {
public var UTC : String {
return dateFormatterUTC.stringFromDate(self)
}
}
这并不比静态class成员差多少,因为Swift的private
是file-private,而不是类型-私有。 dateFormatterUTC
的这两个声明具有相同的作用域。即使在第一个示例中,NSDate.dateFormatterUTC
在声明它的整个文件中都可以访问。
我同意静态版本更可取,但仅出于风格原因:我喜欢它紧挨着使用它的东西缩进的方式。
作为, this approach assumes UTC
will only ever be called from one thread. Although static let
and global let
are both thread-safe in Swift, the NSDateFormatter
class is not! Looks like 。呸
不过,在提到单例的旁边加上线程安全警告总是好的。如果您确实想在多个线程中使用非线程安全的助手对象,请考虑在每次调用时创建一个新的助手,或者使用 NSThread.currentThread().threadDictionary
创建一个线程实例。在选择更复杂的线程本地选项之前,请务必进行一些分析以确保您确实解决了性能问题。
在这里的几个地方,有人建议在 NSDate
的扩展中使用计算的 属性 可能是通过 [=15= 获取日期的字符串版本的好方法],像这样:
extension NSDate {
public var UTC : String {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
formatter.timeZone = NSTimeZone(abbreviation: "UTC")
return formatter.stringFromDate(self)
}
}
然而,分配一个 NSDateFormatter
是昂贵的,建议它们被创建一次并缓存。每次格式化日期时,上面的代码都会创建 NSDateFormatter
,我想知道是否有一种方法可以在扩展中创建 NSDateFormatter
once 以供重用?
显然,我可以在扩展之外创建它一次,但这似乎破坏了表征 类.
的封装我想起了:https://xkcd.com/1179/ !!
您可以将静态成员添加到 class 扩展,就像在 classes 上一样。使用时需要在静态成员名称前加上 class 前缀,例如NSDate.dateFormatterUTC
,即使您在同一个 class.
这个有效:
extension NSDate {
private static let dateFormatterUTC: NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
formatter.timeZone = NSTimeZone(abbreviation: "UTC")
return formatter
}()
public var UTC : String {
return NSDate.dateFormatterUTC.stringFromDate(self)
}
}
仅仅使用私有常量也不是世界上最糟糕的事情:
private let dateFormatterUTC: NSDateFormatter = {
let formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss ZZZ"
formatter.timeZone = NSTimeZone(abbreviation: "UTC")
return formatter
}()
extension NSDate {
public var UTC : String {
return dateFormatterUTC.stringFromDate(self)
}
}
这并不比静态class成员差多少,因为Swift的private
是file-private,而不是类型-私有。 dateFormatterUTC
的这两个声明具有相同的作用域。即使在第一个示例中,NSDate.dateFormatterUTC
在声明它的整个文件中都可以访问。
我同意静态版本更可取,但仅出于风格原因:我喜欢它紧挨着使用它的东西缩进的方式。
作为UTC
will only ever be called from one thread. Although static let
and global let
are both thread-safe in Swift, the Looks like NSDateFormatter
class is not!
不过,在提到单例的旁边加上线程安全警告总是好的。如果您确实想在多个线程中使用非线程安全的助手对象,请考虑在每次调用时创建一个新的助手,或者使用 NSThread.currentThread().threadDictionary
创建一个线程实例。在选择更复杂的线程本地选项之前,请务必进行一些分析以确保您确实解决了性能问题。