仍然对 Swift DateFormatter 和 .dateFormat 效率感到困惑
Posted
技术标签:
【中文标题】仍然对 Swift DateFormatter 和 .dateFormat 效率感到困惑【英文标题】:Still confused on Swift DateFormatter & .dateFormat efficiency 【发布时间】:2017-10-27 00:45:37 【问题描述】:我知道在 ios/Swift 中创建 DateFormatters 和设置 .dateFormats 很昂贵,我在 SO 和博客中阅读了很多不同的观点,但我仍然不确定有效处理 DateFormatter
的最佳方法和.dateFormat
。具体来说,我正在使用一个大致模仿苹果 iPhone 天气应用程序 UI 的应用程序。日期通过 API 以timeIntervalSince1970
/Unix 格式到达。在每个视图控制器上,我将使用一个 .dateFormat
来表示当前天气,例如“EEEE, MMM dd, y”,另一个用于在每日天气表视图中的 7 个单元格中的每个单元格中格式化日期,例如“EEEE”,另一个在水平滚动的集合视图中以 24 个单元格显示一个小时,例如“哈”。用户还为他们保存的每个位置翻阅各种视图控制器。我没有注意到对性能有太大影响,但我真的很想确保我的效率最高,并正确地考虑到这一点(例如,单例是要走的路吗?)。
我创建了一个带有单个DateFormatter
作为静态变量的单例,还创建了一个函数来设置日期格式化程序的.dateFormat
和.timeZone
(见下文)。根据之前的阅读,我假设如果我坚持使用 iOS 10 或更高版本,我不必担心线程安全性,而且在这类应用程序中这可能不是问题。
class Formatter
static var dateFormatter = DateFormatter()
private init()
static func formatTimeForTimeZone(unixDate: TimeInterval, formatString: String, timeZone: String) -> String
let usableDate = Date(timeIntervalSince1970: unixDate)
self.dateFormatter.dateFormat = formatString
self.dateFormatter.timeZone = TimeZone(identifier: timeZone)
let dateString = self.dateFormatter.string(from: usableDate)
return dateString
每次我需要在视图或自定义单元格类中设置日期时,我只需调用该函数,并传入适当的值,如下所示:
let dateString = Formatter.formatTimeForTimeZone(unixDate: someTime, formatString: someFormatString, timeZone: someTimeZone)
由于我在每次调用(在每个单元格中)设置一个 .formatString ,这种方法并没有为我节省太多,这是否正确?如果是这样,是否有更合理的方法?非常感谢您让我直截了当。
【问题讨论】:
这对我来说似乎是过早的优化。除非您有数千/数万个日期要使用DateFormatter
s 进行格式化,否则您不应该真正担心它的性能。特别是如果您在您的应用支持的最旧设备上测试您的代码并且没有发现任何性能问题,那么您的代码应该可以继续使用。
你不应该命名你的类格式化程序。 Swift 已经有一个类带格式化程序。只需使用扩展将您的静态方法或属性添加到它。 developer.apple.com/documentation/foundation/formatter
顺便说一句,无需使用var
将您的 dateFormatter 声明为变量。 DateFormatter
它是一个类,因此即使您使用 let
将其声明为常量,您也可以更改其属性。
关于你的问题。这不是单例。您甚至没有在任何地方实例化您的 Formatter 类。如果您想学习如何创建单例,您应该阅读采用 Cocoa 设计模式指南。 developer.apple.com/library/content/documentation/Swift/… 和这个答案 ***.com/questions/28016578/…
谢谢,Leo - 非常有帮助。我在下面发布了一个从 Sandmoose 的代码修改的替代 DateFormatter 缓存解决方案(希望这个礼仪是正确的),但我想知道设置缓存的 DateFormatter 的 .timeZone 或使用 .string(from: somePOSIXdate) 是否与设置 .dateFormat 或创建一样昂贵一个新的日期。如果是这样,那么我并没有真正获得希望的效率。感谢您的建议!
【参考方案1】:
编辑以获得更好的答案: 感谢 Leo 让我直截了当并提供建议。 在查看了选项并尝试了一些事情之后,我最终使用的解决方案是在每个需要 dateFormatter 的类的顶部创建一个私有的全局数据格式化程序,其中包含特定于类的 dateFormat String。全球性提供了持久性,因此我不会重新创建 DateFormatter 或设置 .dateFormat 字符串(据称都是昂贵的)。全局如下,仅更改类到类是 .dateFormat 字符串
private let dateFormatter: DateFormatter =
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "EEEE, MMM dd, y"
return dateFormatter
()
然后我创建了 TimeInterval 的扩展来处理我需要的格式,采用 IANA 时区字符串和 DateFormatter(在调用时传入类的全局)。
extension TimeInterval
func format(timeZone: String, dateFormatter: DateFormatter) -> String
let usableDate = Date(timeIntervalSince1970: self)
dateFormatter.timeZone = TimeZone(identifier: timeZone)
let dateString = dateFormatter.string(from: usableDate)
return dateString
如果有人也在寻找替代方案,这里 mluton/sandmoose 提供的缓存方法非常好: https://gist.github.com/mluton/98ab2b82bd18f7a7f762#file-cacheddateformatter-swift
【讨论】:
以上是关于仍然对 Swift DateFormatter 和 .dateFormat 效率感到困惑的主要内容,如果未能解决你的问题,请参考以下文章
在 Swift 中使用 DateFormatter 和 TimeZone 来格式化日期
在swift中使用DateFormatter时发生错误[重复]