在这里的几个地方,建议在NSDate扩展名内使用计算属性可能是一种通过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)
    }
}

但是,分配NSDateFormatter是昂贵的,建议将它们创建一次并进行缓存。上面的代码每次格式化日期时都会创建NSDateFormatter,我想知道是否有一种方法可以在扩展名中一次创建NSDateFormatter以便重复使用?

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

我想起了:https://xkcd.com/1179/ !!

最佳答案

您可以像在类上一样将静态成员添加到类扩展。使用类名时,您需要在类名之前加上静态成员名。 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)常量也不是世界上最糟糕的事情:
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是文件专用的,而不是类型专用的。这两个dateFormatterUTC声明具有相同的作用域。即使在第一个示例中,NSDate.dateFormatterUTC也可以在声明它的整个文件中访问。

我确实同意使用静态版本是可取的,但仅出于风格方面的原因:我喜欢在使用它的对象旁边紧缩它的方式。

Gwendal wisely notes above一样,此方法假定UTC仅从一个线程中调用。尽管static let和global let在Swift中都是线程安全的,但是NSDateFormatter类不是!看起来像it’s threadsafe starting in iOS 7。 ew

尽管如此,始终最好在提及单例的旁边保留线程安全警告。如果确实要在多个线程中使用非线程安全的帮助程序对象,请考虑在每个调用上创建一个新的帮助程序,或者考虑使用NSThread.currentThread().threadDictionary创建每个线程的实例。在选择更复杂的线程本地选项之前,请务必进行一些性能分析,以确保您确实在解决性能问题。

关于swift - 如何在Swift类扩展中创建 'static'?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33602923/

10-14 14:05
查看更多