【问题标题】:NSAttributedString initialization throws NSRangeExceptionNSAttributedString 初始化抛出 NSRangeException
【发布时间】:2015-04-07 04:22:45
【问题描述】:

我写了一个简单的扩展来解码 html 实体:

extension String {
    func htmlDecode() -> String {
        if let encodedData = self.data(using: String.Encoding.unicode) {
            let attributedString = try! NSAttributedString(data: encodedData, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.unicode], documentAttributes: nil)
            return attributedString.string
        }
        return self
    }
}

现在它在if let attributedString … 行抛出错误:

*** 由于未捕获的异常“NSRangeException”而终止应用程序,原因:“*** -[__NSArrayM objectAtIndex:]: index 4 beyond bounds [0 .. 2]”

self 不是零什么的,只是一个String 像这样:

self = (String) "...über 25'000 Franken..."

这个奇怪的NSArray-exception 是从哪里来的?

【问题讨论】:

  • 实际上我无法重现您的示例输入字符串的问题。
  • 这很奇怪。如果我快速滚动浏览我的UITableView,就会发生这种情况。我必须进一步调查。
  • @FabioPoloni 您找到任何解决方案了吗?我的经历完全一样:只有当我快速滚动 tableView 时才会发生这种情况......
  • @Bonan 此代码仍在我的应用程序中,并且时不时会崩溃 - 但是,我刚刚将其更新到 Swift 3!

标签: ios swift nsattributedstring


【解决方案1】:

黑暗中的一枪:你确保初始化发生在主线程上吗?

我遇到了完全相同的问题。我注意到在我的情况下,异常发生在可重现的条件下(UICollectionViewController 中的动画),但我无法找到实际原因。我最好的猜测是这是一个框架错误,所以我也建议你提交一个雷达。

我最终将我的 HTML 格式的字符串预渲染到缓存(又名数组)中,然后按需加载 NSAttributedStrings。

请注意,尽管此解决方案可能不适合您的用例,因为我一次只需要处理有限数量的格式化字符串,因此知道提前呈现它们的费用。

【讨论】:

    【解决方案2】:

    在我的例子中,发生这种情况是因为我试图从处于分离状态的UICollectionViewCell 中实例化一个NSAttributedString(在它被插入到父 UICollectionView 之前)。

    【讨论】:

      【解决方案3】:

      似乎是一个错误,可能与 Swift 字符串处理字符的方式与 NSString 不同。

      我会归档雷达。

      【讨论】:

        【解决方案4】:

        DispatchQueue.main.async { let text = yourHtmlText.htmlDecode() }

        【讨论】:

        • 请不要只发布代码作为答案,还要解释您的代码的作用以及它如何解决问题的问题。带有解释的答案通常更有帮助、质量更好,并且更有可能吸引投票。
        【解决方案5】:

        我刚刚遇到了这个错误,但出现了另一个错误:

        *** 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“-[_SwiftValue unsignedIntegerValue]:无法识别的选择器发送到实例 0x60000024b790”

        并在这段代码中发现了一个严重的错误:

        我将 String.Encoding.unicode(一个 Swift 值)传递给了一个使应用程序崩溃的 Objective-C 方法。使用String.Encoding.unicode.rawValue后崩溃消失:

        extension String {
            func htmlDecode() -> String {
                if let encodedData = self.data(using: String.Encoding.unicode) {
                    if let attributedString = try? NSAttributedString(data: encodedData, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.unicode.rawValue], documentAttributes: nil) {
                        return attributedString.string
                    }
                }
                return self
            }
        }
        

        【讨论】:

        • 有趣。我仍在使用 Swift 2.2,我遇到了完全相同的问题。但是,我没有使用 String.Encoding.unicode.rawValue(在 Swift 2.2 中不可用),而是使用 NSUTF8StringEncoding 来生成数据和 NSAttributedString,所以至少在我的情况下,这不是由于 Swift 特定类型造成的。跨度>
        • @Bonan 您能否详细说明您的具体用例?查看崩溃堆栈跟踪,我的问题似乎与 UICollectionView 动画内容密切相关,但我无法确定。我的解决方法(见我的回答)是提前进行转换,而不是按需进行。
        • @ahaese 如果使用 Xcode 8、iOS 10.2、Swift 3 在 cellForRowAt... >
        • @ahaese 我尝试使用非常相似的代码,大部分时间它都可以工作,但在极少数情况下应用程序会崩溃。在更新单元格之前预先生成属性字符串对我来说效果很好,也消除了表格滚动上的 cpu 开销。
        • 我仍然收到来自 Swift 3 的答案的代码错误(由于未捕获的异常 'NSRangeException' 导致应用程序终止,原因:'*** -[__NSArrayM objectAtIndexedSubscript:]: index 0超出空数组的界限')
        猜你喜欢
        • 2020-11-20
        • 2015-12-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-04-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多