Xcode 11 破坏了 DateFormatter?

Posted

技术标签:

【中文标题】Xcode 11 破坏了 DateFormatter?【英文标题】:Xcode 11 broke DateFormatter? 【发布时间】:2019-10-03 21:21:31 【问题描述】:

有一天,该应用程序成功了。第二天我更新到 Xcode 11,现在应用程序在图片中的第 27 行(执行第 15 行时)出现“意外发现 nil”崩溃。

我问了我的同事,他还没有 Xcode 11,他没有崩溃。我们在同一个分支/提交......一切。

有什么建议吗?有什么办法吗?

我的代码:

// ticket.timeOrdered == "2019-10-03 22:54:57 +0000"

let ticketDate = ticket.timeOrdered.asCrazyDate.timeIntervalSince1970

extension String 

    var asCrazyDate: Date 
        let dateFormatterGet = DateFormatter()
        dateFormatterGet.dateFormat = "yyyy-MM-dd HH:mm:ss +zzzz"
        dateFormatterGet.timeZone = .current
        return dateFormatterGet.date(from: self)!
    

【问题讨论】:

可能是这个:***.com/questions/40692378/… 顺便说一句 - 根本不需要您的 asCrazyDate 方法。只需通过消除不必要的字符串插值来修复getDate() 这个问题的目的是为什么它适用于 xcode 10 而不是 xcode 11。我展示的代码是对正在发生的事情的重构“摘要”。我刚刚卸载了 Xcode 11 并重新安装了 Xcode 10.3。现在一切正常。 "yyyy-MM-dd HH:mm:ss Z" 可以。但也要设置你的locale What does "fatal error: unexpectedly found nil while unwrapping an Optional value" mean?的可能重复 【参考方案1】:

日期格式字符串不正确。 +zzzz 不是可接受的格式。请参阅Date Format Patterns 中表的时区相关部分。 + 不应该在那里。 zzzz 用于时区的详细描述(例如“太平洋夏令时间”)。您可以通过使用相同的格式化程序从 Date() 构建字符串来验证这一点,您会发现它并没有像您预期的那样生成 +0000

最新版 SDK 的日期格式化程序不再像以前的版本那样容忍此类格式字符串错误。但与其恢复你的 Xcode 版本,你真的应该只修复那个日期格式字符串。例如,您可以使用Z 而不是+zzzz,这将正确地将+0000(或其他)解释为字符串的时区部分。


如果你不介意的话,还有其他一些建议:

    在这个例子中你不需要asCrazyDate。获取日期是没有意义的,使用字符串插值来构建字符串表示,然后使用格式化程序将字符串转换回日期(您最初开始使用的日期)。您可以直接使用Date

    func getDate() -> TimeInterval 
        return Date().timeIntervalSince1970
    
    

    众所周知,日期格式化程序的创建需要大量计算,如果您经常使用此计算属性,这会真正影响性能。如果可能,最好将日期格式化程序实例化一次。

    如果您出于某种原因尝试构建一些不变的日期字符串,最好使用ISO8601DateFormatter 之类的东西。所以不要使用字符串插值来构建你的日期字符串,也不要构建你自己的格式化程序。

    let formatter = ISO8601DateFormatter()
    
    let now = Date()
    let string = formatter.string(from: now) // not "\(now)"
    
    let date = formatter.date(from: string)
    
    print(now, string, date)
    

    如果您不喜欢这种日期格式(也许您已经使用这种字符串格式存储了日期),如果必须的话,您可以使用自定义的dateFormat 字符串。但正如Technical Q&A 1480 建议的那样,您可能想要设置locale(我也建议设置timeZone,这样您的日期字符串就可以比较了)。

    let formatter = DateFormatter()
    formatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
    formatter.locale = Locale(identifier: "en_US_POSIX")
    formatter.timeZone = TimeZone(secondsFromGMT: 0)
    

【讨论】:

非常有用,谢谢! getDate 函数只是显示堆栈溢出是我试图完成的缩短版本,但回想起来是一个不好的例子。我不知道 DateFormatters 的使用成本很高(坦率地说,我什至不知道如何解决这个问题)我会更仔细地研究它,并尝试一些关于如何使用我的自定义格式化程序的建议。再次感谢 请参阅ios App Performance: Responsiveness 的“性能策略”部分,了解此性能问题。它已经过时了,专注于 Objective-C 和 NSDateFormatter,但问题与 DateFormatter 相同。

以上是关于Xcode 11 破坏了 DateFormatter?的主要内容,如果未能解决你的问题,请参考以下文章

Java 2012-006 更新破坏了 xCode 上传

XCode 7.3 破坏了 Bridging-Header.h?

XCode 7.3 破坏了 Bridging-Header.h?

更新到 Xcode 13 后出现错误破坏了应用程序

Xcode 更新破坏了 gcloud 和 gsutil

新版本的 Xcode 破坏了音频播放代码