如何创建一个静态的?在Swift类扩展中?

时间:2015-11-09 05:16:05

标签: swift date nsdateformatter

在这里的几个地方,有人建议在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}}一次以供重复使用?

显然,我可以在扩展名之外创建一次,但这似乎打败了表征类的封装。

我想起了:enter image description here !!

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中都是线程安全的,但 NSDateFormatter类不是!看起来像it’s threadsafe starting in iOS 7。呼。

仍然,总是很好的保持线程安全警告旁边提到单身人士。如果您确实想要使用来自多个线程的非线程安全帮助程序对象,请考虑在每次调用时创建新的帮助程序,或使用NSThread.currentThread().threadDictionary创建每个线程的实例。在选择更复杂的线程局部选项之前,请务必进行一些分析以确保实际解决性能问题。