【问题标题】:Initialization of NSAttributedString is crashing applicationNSAttributedString 的初始化使应用程序崩溃
【发布时间】:2018-12-28 05:48:05
【问题描述】:

尽管它位于do-catch 块内,但以下代码会崩溃(并非总是但很少)。 Fabric crashlytics 声明异常是 Fatal Exception: NSInternalInconsistencyException 有时是 EXC_BAD_ACCESS KERN_PROTECTION_FAILURE 0x000000016fccb1f8

do {
    return try NSAttributedString(
        data: data,
        options: [
            .documentType:  NSAttributedString.DocumentType.html,
            .characterEncoding: String.Encoding.utf8.rawValue
        ],
        documentAttributes: nil
    )
} catch {
    return NSAttributedString()
}

虽然我阅读了NSAttributedString 的苹果文档,但它声明它应该在主线程上,所以我用Dispatch.main.async 块包围它,但这样做并没有设置NSAttributedString 上设置的样式

【问题讨论】:

  • 会不会是你的数据不对?
  • 这似乎是不可能的,因为我无法复制该问题,并且根据来自数千名用户的应用中心,只有 58 名用户遇到了这些崩溃。

标签: ios swift swift4 crashlytics


【解决方案1】:

根据此处苹果开发者论坛提供的解决方案:https://forums.developer.apple.com/thread/115405

遗憾的是,这是 iOS (r. 23592459) 中的一个已知错误,可能 影响任何从 HTML 构造 NSAttributedString 的人。

除了避免使用此 API 之外,没有好的解决方法 共。我的建议:

如果您要显示大量复杂的 HTML,请使用 WKWebView。

如果这个 HTML 受到高度限制——也许你只是将​​ HTML 用作 转移一组受约束的属性的简单方法,例如粗体和 斜体——创建自己的不依赖 HTML 的标记系统。 或仅针对这些属性解析 HTML 并使用结果 创建你的属性字符串。

很抱歉,这里没有更好的消息。

因此,为避免崩溃,您可能需要避免使用 NSAttributedString( 数据: 函数本身并编写自己的方式来解析 html。

【讨论】:

    【解决方案2】:

    仅在主线程中更新 UI。

    DispatchQueue.main.async {
        textLabel.attributedText = generateAttribString()
    }
    

    【讨论】:

    • 我试过这个,但是这样做不是设置nsattributedstring中提供的样式,只是设置文本。
    • 我想我会应用它并部署然后注意这些崩溃是否消失了。
    【解决方案3】:

    如果您尝试将 HTML 转换为字符串,您可以使用字符串上的扩展名,如下所示:

    extension String {
        var htmlToAttributedString: NSAttributedString? {
            do {
                return try NSAttributedString(data: Data(utf8),
                                              options: [.documentType: NSAttributedString.DocumentType.html,
                                                        .characterEncoding: String.Encoding.utf8.rawValue],
                                              documentAttributes: nil)
            } catch {
                print("error: ", error)
                return nil
            }
        }
        var htmlToString: String {
            return htmlToAttributedString?.string ?? ""
        }
    }
    

    【讨论】:

    • 做的完全一样,运行完美,但有时在某些设备上崩溃。
    • 可能原因是您的数据不正确。没有其他任何东西会导致此代码崩溃。
    • 如果数据有误,应该在catch块中提供服务
    • 在我的情况下不会因为“Data(utf8)”如果没有将String转换为Data并且它不会进入catch块,可能会导致崩溃。
    • 数据是这样初始化的guard let data = htmlCSSString.data(using: .utf8) else { return NSAttributedString() }
    猜你喜欢
    • 1970-01-01
    • 2016-04-22
    • 2021-11-19
    • 2016-04-26
    • 2012-10-20
    • 1970-01-01
    • 2018-12-30
    • 2014-03-29
    • 1970-01-01
    相关资源
    最近更新 更多