在这里的几个地方,有人建议在NSDateFormatter
的扩展名中使用计算属性可能是通过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)
}
}
获取日期的字符串版本的好方法,如下所示: / p>
NSDateFormatter
但是,分配NSDateFormatter
代价很高,建议创建一次并缓存它们。上面的代码会在每次格式化日期时创建NSDateFormatter
,并且我想知道是否有一种方法可以在扩展程序中创建{{1}}一次以供重复使用?
显然,我可以在扩展名之外创建一次,但这似乎打败了表征类的封装。
答案 0 :(得分:5)
您可以将静态成员添加到类扩展,就像在类上一样。使用时,您需要在类名称前加上静态成员名称,例如: NSDate.dateFormatterUTC
,即使您在同一个班级中使用它。
这有效:
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)
}
}
这并不比静态类成员差很多,因为Swift的private
是文件私有,而不是 type-private 。 dateFormatterUTC
的这两个声明具有相同的范围。即使在第一个示例中,NSDate.dateFormatterUTC
也可以在声明的整个文件中访问。
我同意静态版本更可取,但仅出于文体原因:我喜欢它在使用它的东西旁边缩进的方式。
作为Gwendal wisely notes above,此方法假设UTC
只会从一个线程调用。虽然static let
和全局let
在Swift中都是线程安全的,但 看起来像it’s threadsafe starting in iOS 7。呼。NSDateFormatter
类不是!
仍然,总是很好的保持线程安全警告旁边提到单身人士。如果您确实想要使用来自多个线程的非线程安全帮助程序对象,请考虑在每次调用时创建新的帮助程序,或使用NSThread.currentThread().threadDictionary
创建每个线程的实例。在选择更复杂的线程局部选项之前,请务必进行一些分析以确保实际解决性能问题。