iOS 15 使用 HTML 字符串初始化 NSAttributedString 时崩溃

问题描述 投票:0回答:2

我有一个扩展可以将 HTML 字符串转换为

NSAttributedString

iOS 15 发布后,我看到了很多用户的崩溃情况。所有这些崩溃都发生在 iOS 15 上,并且发生在主线程

这是来自 Crashlytics 的典型崩溃报告。

Crashed: com.apple.main-thread
0  libsystem_platform.dylib       0x1f29d60c0 _os_unfair_lock_recursive_abort + 36
1  libsystem_platform.dylib       0x1f29d0a10 _os_unfair_lock_lock_slow + 304
2  Foundation                     0x183d5e730 -[NSProcessInfo(NSProcessInfoHardwareState) isLowPowerModeEnabled] + 68
3  WebCore                        0x192011004 <redacted> + 56
4  CoreFoundation                 0x182535ee8 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 28
5  CoreFoundation                 0x1825d1b9c ___CFXRegistrationPost_block_invoke + 52
6  CoreFoundation                 0x1825a4f54 _CFXRegistrationPost + 456
7  CoreFoundation                 0x18254bd54 _CFXNotificationPost + 716
8  Foundation                     0x183d50028 -[NSNotificationCenter postNotificationName:object:userInfo:] + 96
9  Foundation                     0x183dc89d4 NSProcessInfoNotifyPowerState + 188
10 Foundation                     0x183d5e768 -[NSProcessInfo(NSProcessInfoHardwareState) isLowPowerModeEnabled] + 124
11 WebCore                        0x191595118 <redacted> + 96
12 WebCore                        0x19201116c WebCore::LowPowerModeNotifier::LowPowerModeNotifier(WTF::Function<void (bool)>&&) + 52
13 WebCore                        0x192f36c4c WebCore::Page::Page(WebCore::PageConfiguration&&) + 1848
14 WebKitLegacy                   0x1a605ae34 -[WebView(WebPrivate) _commonInitializationWithFrameName:groupName:] + 3060
15 WebKitLegacy                   0x1a605a214 -[WebView(WebPrivate) _initWithFrame:frameName:groupName:] + 116
16 UIFoundation                   0x18d306028 -[NSHTMLReader _loadUsingWebKit] + 832
17 UIFoundation                   0x18d30715c -[NSHTMLReader attributedString] + 32
18 UIFoundation                   0x18d2c04e8 _NSReadAttributedStringFromURLOrData + 8420
19 UIFoundation                   0x18d2be378 -[NSAttributedString(NSAttributedStringUIFoundationAdditions) initWithData:options:documentAttributes:error:] + 156
20 MyAppExtensions                 0x108aa0fc4 _hidden#912_ + 4374482884 (__hidden#360_:4374482884)
21 MyAppExtensions                 0x108aa0894 NSAttributedString.init(htmlString:font:useDocumentFontSize:) + 36 (__hidden#925_:36)
22 MyAppName                           0x1045eca18 {foo_class}.convertHTML(_:) + 670 (xxxx.swift:670)
23 MyAppName                           0x1045e5c58 {foo_class}.some_function_3 + 620 (xxxx.swift:620)
24 MyAppName                           0x1045e4760 {foo_class}.some_function_2 + 212 (xxxx.swift:212)
25 MyAppName                           0x1045e4200 {foo_class}.some_function_1 + 138 (xxxx.swift:138)
.
.
.
42 UIKitCore                      0x184b5e1d0 _UIGestureRecognizerSendTargetActions + 116
43 UIKitCore                      0x184b2705c _UIGestureRecognizerSendActions + 284
44 UIKitCore                      0x184b60580 -[UIGestureRecognizer _updateGestureForActiveEvents] + 636
45 UIKitCore                      0x184b186fc _UIGestureEnvironmentUpdate + 1988
46 CoreFoundation                 0x18254c570 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 36
47 CoreFoundation                 0x18251b854 __CFRunLoopDoObservers + 572
48 CoreFoundation                 0x1825168ec __CFRunLoopRun + 1052
49 CoreFoundation                 0x18252a3c8 CFRunLoopRunSpecific + 600
50 GraphicsServices               0x19dd3b38c GSEventRunModal + 164
51 UIKitCore                      0x184ed00bc -[UIApplication _run] + 1100
52 UIKitCore                      0x184c4dbe8 UIApplicationMain + 2124
53 libswiftUIKit.dylib            0x199afe184 UIApplicationMain(_:_:_:_:) + 104
54 MyAppName                      0x1043a5894 main + 7 (main.swift:7)
55 dyld                           0x106b81a24 start

以下是将HTML转换为

NSAttributedString
的代码:

extension NSAttributedString {
  convenience public init(htmlString html: String, font: UIFont? = nil, useDocumentFontSize: Bool = true) throws {
    let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
      .documentType: NSAttributedString.DocumentType.html,
      .characterEncoding: String.Encoding.utf8.rawValue
    ]

    guard let data = html.data(using: .utf8, allowLossyConversion: true) else {
      self.init(string: "")
      return
    }

    guard let fontFamily = font?.familyName else {
      try self.init(data: data, options: options, documentAttributes: nil)
      return
    }

    let attr = try NSMutableAttributedString(data: data, options: options, documentAttributes: nil)

    let fontSize: CGFloat? = useDocumentFontSize ? nil : font!.pointSize
    let range = NSRange(location: 0, length: attr.length)
    attr.enumerateAttribute(.font, in: range, options: .longestEffectiveRangeNotRequired) { attrib, range, _ in
      if let htmlFont = attrib as? UIFont {
        let traits = htmlFont.fontDescriptor.symbolicTraits
        var descrip = htmlFont.fontDescriptor.withFamily(fontFamily)

        if (traits.rawValue & UIFontDescriptor.SymbolicTraits.traitBold.rawValue) != 0 {
          descrip = descrip.withSymbolicTraits(.traitBold)!
        }

        if (traits.rawValue & UIFontDescriptor.SymbolicTraits.traitItalic.rawValue) != 0 {
          descrip = descrip.withSymbolicTraits(.traitItalic)!
        }

        attr.addAttribute(.font, value: UIFont(descriptor: descrip, size: fontSize ?? htmlFont.pointSize), range: range)
      }
    }

    self.init(attributedString: attr)
  }

顺便说一句,我正在使用 Xcode 12.5 来存档发布版本。

html swift crash nsattributedstring ios15
2个回答
2
投票

苹果开发者论坛中关于此崩溃的讨论此处

您可能需要避免使用 NSAttributedString(data: , options: [.documentType: NSAttributedString.DocumentType.html] 本身并自行解析 HTML 字符串来生成属性字符串。也许,您可以使用一些开源项目GitHub,例如DTCoreText


0
投票

在此处输入图像描述以防万一它对任何人都有用,禁用 Malloc 堆栈日志记录不再导致我的设备崩溃。编辑方案 -> 诊断 -> 取消选中该框。

© www.soinside.com 2019 - 2024. All rights reserved.