访问 NSError.localizedDescription 时偶尔崩溃

Occasional crash when accessing NSError.localizedDescription

在 Swift 1.2 应用程序中,我有一些记录 NSError 对象的代码。在极少数情况下,我从 Crashlytics 收到崩溃报告,指出访问 localizedDescription 属性 导致了崩溃。

这是我的错误记录函数:

func trackError(error: NSError)
{
    var props = [String: AnyObject]()

    // CRASHES HERE
    props["NSErrorLocalized"] = error.localizedDescription

    props["NSErrorCode"] = error.code
    props["NSErrorDomain"] = error.domain

    if let userInfo = error.userInfo {
        props["NSErrorUserInfo"] = userInfo
    }

    self.trackEvent("Error", withProperties: props)
}

这是 Crashlytics 报告的调用堆栈:

0 CoreFoundation  CFHash + 129
1 CoreFoundation  CFBasicHashFindBucket + 1204
2 CoreFoundation  CFBasicHashFindBucket + 1204
3 CoreFoundation  CFDictionaryGetValue + 106
4 CoreFoundation  _CFErrorCreateLocalizedDescription + 266
5 Foundation      -[NSError localizedDescription] + 82

我正在考虑直接访问 error.userInfo 中的 NSLocalizedDescriptionKey 而不是通过 localizedDescription 属性,但由于调用堆栈暗示它在访问字典时崩溃(这很可能是 userInfo 字典),恐怕它不会解决任何问题。

如果有 none,我不介意在我的错误日志中不包含 localizedDescription,但我需要一种安全的方法来检查是否有 localizedDescription 而不会崩溃...

可能值得注意的事情:导致此崩溃的 NSError 对象似乎是由 Parse SDK 返回的对象。我无法确定这一点,但我的其余日志中有一些线索似乎暗示了这一点。

我试图通过对 Parse SDK 的各种调用强制错误情况来重现此问题,但我的错误记录代码处理它们没有任何问题并且 localizedDescription 属性 returns没有崩溃的有效字符串。

还有其他人看到了这个并且对发生的事情有任何线索吗?

你检查过 localizedDescription 属性 没有设置为 nil 吗?尝试这样的事情...

if let errorLocalizedDescription = localizedDescription as! String {
    props["NSErrorLocalized"] = error.localizedDescription
}

可能导致崩溃的一种可能方式是(在 Objective-C 中)产生错误,例如 [NSError new][[NSError alloc] init](即未调用指定的初始值设定项)。至少在 iOS9 中,那个 returns 是一个有效的实例,但它的内部没有正确初始化,如果你调用它的方法可能会崩溃。仅调用 -userInfo returns 一个空字典,但尝试访问其他内部状态(如 -localizedDescription 和类似方法)会导致崩溃。

我最终解决了这个问题:

if let localizedDescription = error.userInfo[NSLocalizedDescriptionKey] as? String {}

而不是直接访问 属性。