草庐IT

ios - 将 HTML 转换为属性字符串时 NSAttributedString 崩溃

coder 2023-09-04 原文

我遇到这样一种情况,try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil) 使应用程序崩溃。

在控制台中它说: void _prepareForCAFlush(UIApplication *__strong)() 断言失败

该函数在 extension String 中调用。 当我在控制台中“po”值时:

(lldb) po self
<p>Obfuscated string\n</p>


(lldb) po data`
450 bytes
  count : 450
    pointer : 0x00007fd283d75630
    pointerValue : 140542131787312

(lldb) po NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
Obfuscated string
{
            NSColor = "kCGColorSpaceModelRGB 0 0 0 1 ";
            NSFont = "<UICTFont: 0x7fd283c47330> font-family: \"Helvetica\"; font-weight: normal; font-style: normal; font-size: 15.00pt";
            NSKern = 0;
            NSParagraphStyle = "Alignment 4, LineSpacing 0, ParagraphSpacing 15, ParagraphSpacingBefore 0, HeadIndent 0, TailIndent 0, FirstLineHeadIndent 0, LineHeight 19/0, LineHeightMultiple 0, LineBreakMode 0, Tabs (\n), DefaultTabInterval 36, Blocks (\n), Lists (\n), BaseWritingDirection 0, HyphenationFactor 0, TighteningForTruncation NO, HeaderLevel 0";
            NSStrokeColor = "kCGColorSpaceModelRGB 0 0 0 1 ";
            NSStrokeWidth = 0;
}

字符串存在于标签中,显示在 UITableViewCell 中。 当“键盘框架改变”时,该功能在特定情况下崩溃。 iOS 正在再次绘制表格单元格,这会导致重新绘制其内容。

崩溃发生在主线程上,所以函数是在主线程上调用的。

这次崩溃的原因是什么?我该如何解决?

编辑: TableView 单元格代码

UITableViewDataSource 生成单元格:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cellID = cellIdentifier(for: message)
        let cell = tableView.dequeueReusableCell(withIdentifier: cellID) as! MessageTableViewCell
        cell.message = message
        cell.setOutletValues()
        cell.selectionStyle = .none
        cell.delegate = self
        return cell

}

Cell 的实现:

class MessageTableViewCell: UITableViewCell {

    var message: Message!

    // Message Body View
    @IBOutlet weak var messageBodyView: ZeroPaddingTextView!

    func setOutletValues() {
        setMessageBodyOutletValues()
    }

    internal func setMessageBodyOutletValues() {
        if let body = message.body {
            messageBodyView.attributedText = body.htmlToPlainAttributedString()
        }
    }
}

创建普通属性字符串的函数,它为样式添加了一些 HTML(这是由于通过 API 传入的内容,它需要一些添加)。

func htmlToPlainAttributedString() -> NSAttributedString {
    let contentString = replacingOccurrences(of: "\n", with: "<br>")
    let styleSheet = "body {font-family: sans-serif; font-size: 15px; color: #000000;}\n a {text-decoration: none;}\n"
    let body = "<body>\(contentString)</body>"
    let html = "<html><head><style type=\"text/css\">\(styleSheet)</style></head>\(body)</html>"
    if let data = html.data(using: String.Encoding.unicode, allowLossyConversion: true) {
        do {
            return try NSAttributedString(data: data, options: [
                NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
        } catch {
            return NSAttributedString()
        }
    }
    return NSAttributedString()
}

控制台崩溃输出:

2017-09-05 22:37:14.692 trustedfamily-ios[70389:10080542] *** Assertion failure in void _prepareForCAFlush(UIApplication *__strong)(), /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3600.7.47/UIApplication.m:2395
2017-09-05 22:38:14.532 trustedfamily-ios[70389:10080542] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unexpected start state'
*** First throw call stack:
(
    0   CoreFoundation                      0x000000010452ab0b __exceptionPreprocess + 171
    1   libobjc.A.dylib                     0x00000001035e8141 objc_exception_throw + 48
    2   CoreFoundation                      0x000000010452ecf2 +[NSException raise:format:arguments:] + 98
    3   Foundation                          0x00000001031b769b -[NSAssertionHandler handleFailureInFunction:file:lineNumber:description:] + 165
    4   UIKit                               0x0000000105a31575 _prepareForCAFlush + 499
    5   UIKit                               0x0000000105a6346b _beforeCACommitHandler + 15
    6   CoreFoundation                      0x00000001044d0717 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    7   CoreFoundation                      0x00000001044d0687 __CFRunLoopDoObservers + 391
    8   CoreFoundation                      0x00000001044b5038 CFRunLoopRunSpecific + 440
    9   UIFoundation                        0x000000010a103edc -[NSHTMLReader _loadUsingWebKit] + 1954
    10  UIFoundation                        0x000000010a10522a -[NSHTMLReader attributedString] + 22
    11  UIFoundation                        0x000000010a09ded6 _NSReadAttributedStringFromURLOrData + 8926
    12  UIFoundation                        0x000000010a09bb64 -[NSAttributedString(NSAttributedStringUIFoundationAdditions) initWithData:options:documentAttributes:error:] + 117
    13  trustedfamily-ios                   0x0000000101e9e6ad _TTOFE5UIKitCSo18NSAttributedStringcfzT4dataV10Foundation4Data7optionsGVs10DictionarySSP__18documentAttributesGSqGVs33AutoreleasingUnsafeMutablePointerGSqCSo12NSDictionary____S0_ + 173
    14  trustedfamily-ios                   0x0000000101e9d9d9 _TFE5UIKitCSo18NSAttributedStringCfzT4dataV10Foundation4Data7optionsGVs10DictionarySSP__18documentAttributesGSqGVs33AutoreleasingUnsafeMutablePointerGSqCSo12NSDictionary____S0_ + 89
    15  trustedfamily-ios                   0x0000000101e9d803 _TFE17trustedfamily_iosSS27htmlToPlainAttributedStringfT_CSo18NSAttributedString + 1459
    16  trustedfamily-ios                   0x00000001020152f9 _TFC17trustedfamily_ios20MessageTableViewCell26setMessageBodyOutletValuesfT_T_ + 601
    17  trustedfamily-ios                   0x0000000102013467 _TFC17trustedfamily_ios20MessageTableViewCell15setOutletValuesfT_T_ + 103
    18  trustedfamily-ios                   0x0000000101f9a22f _TFC17trustedfamily_ios32ConversationDetailViewController9tableViewfTCSo11UITableView12cellForRowAtV10Foundation9IndexPath_CSo15UITableViewCell + 1199
    19  trustedfamily-ios                   0x0000000101f9a4d7 _TToFC17trustedfamily_ios32ConversationDetailViewController9tableViewfTCSo11UITableView12cellForRowAtV10Foundation9IndexPath_CSo15UITableViewCell + 87
    20  UIKit                               0x0000000105ba4ab2 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 750
    21  UIKit                               0x0000000105ba4cf8 -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 74
    22  UIKit                               0x0000000105b79639 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2845
    23  UIKit                               0x0000000105b774a4 -[UITableView _setNeedsVisibleCellsUpdate:withFrames:] + 201
    24  UIKit                               0x0000000105b9626a -[UITableView _rectChangedWithNewSize:oldSize:] + 1267
    25  UIKit                               0x0000000105b96a5c -[UITableView setBounds:] + 322
    26  UIKit                               0x0000000105adee73 -[UIView(Geometry) _applyISEngineLayoutValuesToBoundsOnly:] + 598
    27  UIKit                               0x0000000105adf15e -[UIView(Geometry) _resizeWithOldSuperviewSize:] + 125
    28  UIKit                               0x000000010648f0e9 -[UIScrollView(_UIOldConstraintBasedLayoutSupport) _resizeWithOldSuperviewSize:] + 46
    29  CoreFoundation                      0x00000001044bb652 __53-[__NSArrayM enumerateObjectsWithOptions:usingBlock:]_block_invoke + 114
    30  CoreFoundation                      0x00000001044bb56f -[__NSArrayM enumerateObjectsWithOptions:usingBlock:] + 335
    31  UIKit                               0x0000000105addbcc -[UIView(Geometry) resizeSubviewsWithOldSize:] + 183
    32  UIKit                               0x00000001063fa16d -[UIView(AdditionalLayoutSupport) _is_layout] + 168
    33  UIKit                               0x0000000105aea0a6 -[UIView(Hierarchy) _updateConstraintsAsNecessaryAndApplyLayoutFromEngine] + 994
    34  UIKit                               0x0000000105afb55b -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 1268
    35  QuartzCore                          0x00000001057a4904 -[CALayer layoutSublayers] + 146
    36  QuartzCore                          0x0000000105798526 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 370
    37  UIKit                               0x0000000105ae9334 -[UIView(Hierarchy) layoutBelowIfNeeded] + 1108
    38  trustedfamily-ios                   0x0000000101fe3f4c _TFC17trustedfamily_ios32ConversationDetailViewController28changeBottomLayoutConstraintfT2toV12CoreGraphics7CGFloat_T_ + 284
    39  trustedfamily-ios                   0x0000000101fe3fac _TToFC17trustedfamily_ios32ConversationDetailViewController28changeBottomLayoutConstraintfT2toV12CoreGraphics7CGFloat_T_ + 44
    40  trustedfamily-ios                   0x0000000101fe3bf7 _TFFC17trustedfamily_ios32ConversationDetailViewController28changeBottomLayoutConstraintFT2toV12CoreGraphics7CGFloat8animatedSb8durationSd7optionsVSC22UIViewAnimationOptions_T_U_FT_T_ + 39
    41  trustedfamily-ios                   0x0000000101e572d7 _TTRXFo___XFdCb___ + 39
    42  UIKit                               0x0000000105af13da +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 572
    43  UIKit                               0x0000000105af18dd +[UIView(UIViewAnimationWithBlocks) animateWithDuration:delay:options:animations:completion:] + 99
    44  trustedfamily-ios                   0x0000000101fe3b7f _TFC17trustedfamily_ios32ConversationDetailViewController28changeBottomLayoutConstraintfT2toV12CoreGraphics7CGFloat8animatedSb8durationSd7optionsVSC22UIViewAnimationOptions_T_ + 943
    45  trustedfamily-ios                   0x0000000101fe3e1f _TToFC17trustedfamily_ios32ConversationDetailViewController28changeBottomLayoutConstraintfT2toV12CoreGraphics7CGFloat8animatedSb8durationSd7optionsVSC22UIViewAnimationOptions_T_ + 79
    46  trustedfamily-ios                   0x0000000101fe30e6 _TFC17trustedfamily_ios32ConversationDetailViewController23keyboardWillChangeFramefV10Foundation12NotificationT_ + 2278
    47  trustedfamily-ios                   0x0000000101fe3237 _TToFC17trustedfamily_ios32ConversationDetailViewController23keyboardWillChangeFramefV10Foundation12NotificationT_ + 71
    48  CoreFoundation                      0x00000001044c9c2c __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
    49  CoreFoundation                      0x00000001044c9b29 _CFXRegistrationPost + 425
    50  CoreFoundation                      0x00000001044c9892 ___CFXNotificationPost_block_invoke + 50
    51  CoreFoundation                      0x000000010448d102 -[_CFXNotificationRegistrar find:object:observer:enumerator:] + 1826
    52  CoreFoundation                      0x000000010448c261 _CFXNotificationPost + 673
    53  Foundation                          0x00000001030b6ca4 -[NSNotificationCenter postNotificationName:object:userInfo:] + 66
    54  UIKit                               0x000000010649ce05 -[UIInputWindowController postStartNotifications:withInfo:] + 225
    55  UIKit                               0x000000010649f0af __77-[UIInputWindowController moveFromPlacement:toPlacement:starting:completion:]_block_invoke.871 + 381
    56  UIKit                               0x0000000105af13da +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 572
    57  UIKit                               0x0000000105af1853 +[UIView(UIViewAnimationWithBlocks) _animateWithDuration:delay:options:animations:start:completion:] + 116
    58  UIKit                               0x000000010649eacb -[UIInputWindowController moveFromPlacement:toPlacement:starting:completion:] + 1503
    59  UIKit                               0x00000001064a6d5e __43-[UIInputWindowController setInputViewSet:]_block_invoke.1318 + 97
    60  UIKit                               0x000000010649a59a -[UIInputWindowController performOperations:withTemplateNotificationInfo:] + 46
    61  UIKit                               0x00000001064a68ea -[UIInputWindowController setInputViewSet:] + 1753
    62  UIKit                               0x000000010649e14c -[UIInputWindowController performOperations:withAnimationStyle:] + 50
    63  UIKit                               0x0000000106114a8a -[UIPeripheralHost(UIKitInternal) setInputViews:animationStyle:] + 1505
    64  UIKit                               0x0000000106115c4b -[UIPeripheralHost(UIKitInternal) _preserveInputViewsWithId:animated:reset:] + 499
    65  UIKit                               0x0000000105bec35d -[UIViewController _presentViewController:modalSourceViewController:presentationController:animationController:interactionController:completion:] + 1145
    66  UIKit                               0x0000000105bedfae -[UIViewController _presentViewController:withAnimationController:completion:] + 4660
    67  CoreFoundation                      0x00000001044b2c6c __invoking___ + 140
    68  CoreFoundation                      0x00000001044b2b40 -[NSInvocation invoke] + 320
    69  UIKit                               0x0000000105bd1633 -[_UIDelayedPresentationContext finishDelayedPresentation:] + 230
    70  UIKit                               0x0000000105be9416 -[UIViewController _endDelayingPresentation] + 93
    71  CoreFoundation                      0x00000001044b2c6c __invoking___ + 140
    72  CoreFoundation                      0x00000001044b2b40 -[NSInvocation invoke] + 320
    73  FrontBoardServices                  0x000000010a1f25f6 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 24
    74  FrontBoardServices                  0x000000010a1f246d -[FBSSerialQueue _performNext] + 186
    75  FrontBoardServices                  0x000000010a1cb360 -[FBSWorkspace synchronizeSystemAnimationFencesWithCleanUpBlock:] + 1549
    76  UIKit                               0x0000000105a311d4 -[UIApplication _synchronizeSystemAnimationFencesWithSpinCleanUpBlock:] + 543
    77  UIKit                               0x0000000105ab22cd __realPreCommitHandler_block_invoke + 395
    78  QuartzCore                          0x000000010575532c _ZNK2CA11Transaction5Fence13run_callbacksEv + 40
    79  QuartzCore                          0x0000000105727f7c _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 528
    80  QuartzCore                          0x0000000105754130 _ZN2CA11Transaction6commitEv + 468
    81  QuartzCore                          0x0000000105754b37 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 115
    82  CoreFoundation                      0x00000001044d0717 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
    83  CoreFoundation                      0x00000001044d0687 __CFRunLoopDoObservers + 391
    84  CoreFoundation                      0x00000001044b5720 __CFRunLoopRun + 1200
    85  CoreFoundation                      0x00000001044b5016 CFRunLoopRunSpecific + 406
    86  GraphicsServices                    0x000000010a9eda24 GSEventRunModal + 62
    87  UIKit                               0x0000000105a38134 UIApplicationMain + 159
    88  trustedfamily-ios                   0x0000000101ff6837 main + 55
    89  libdyld.dylib                       0x000000010894465d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

最佳答案

尽量让你的html在NSAttributedString里面转换

DispatchQueue.main.async {

关于ios - 将 HTML 转换为属性字符串时 NSAttributedString 崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46056520/

有关ios - 将 HTML 转换为属性字符串时 NSAttributedString 崩溃的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. Ruby 解析字符串 - 2

    我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?

  3. ruby-on-rails - 在 Rails 中将文件大小字符串转换为等效千字节 - 2

    我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,

  4. ruby-on-rails - unicode 字符串的长度 - 2

    在我的Rails(2.3,Ruby1.8.7)应用程序中,我需要将字符串截断到一定长度。该字符串是unicode,在控制台中运行测试时,例如'א'.length,我意识到返回了双倍长度。我想要一个与编码无关的长度,以便对unicode字符串或latin1编码字符串进行相同的截断。我已经了解了Ruby的大部分unicode资料,但仍然有些一头雾水。应该如何解决这个问题? 最佳答案 Rails有一个返回多字节字符的mb_chars方法。试试unicode_string.mb_chars.slice(0,50)

  5. ruby - 将差异补丁应用于字符串/文件 - 2

    对于具有离线功能的智能手机应用程序,我正在为Xml文件创建单向文本同步。我希望我的服务器将增量/差异(例如GNU差异补丁)发送到目标设备。这是计划:Time=0Server:hasversion_1ofXmlfile(~800kiB)Client:hasversion_1ofXmlfile(~800kiB)Time=1Server:hasversion_1andversion_2ofXmlfile(each~800kiB)computesdeltaoftheseversions(=patch)(~10kiB)sendspatchtoClient(~10kiBtransferred)Cl

  6. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  7. ruby-on-rails - Rails 常用字符串(用于通知和错误信息等) - 2

    大约一年前,我决定确保每个包含非唯一文本的Flash通知都将从模块中的方法中获取文本。我这样做的最初原因是为了避免一遍又一遍地输入相同的字符串。如果我想更改措辞,我可以在一个地方轻松完成,而且一遍又一遍地重复同一件事而出现拼写错误的可能性也会降低。我最终得到的是这样的:moduleMessagesdefformat_error_messages(errors)errors.map{|attribute,message|"Error:#{attribute.to_s.titleize}#{message}."}enddeferror_message_could_not_find(obje

  8. ruby - 如何以所有可能的方式将字符串拆分为长度最多为 3 的连续子字符串? - 2

    我试图获取一个长度在1到10之间的字符串,并输出将字符串分解为大小为1、2或3的连续子字符串的所有可能方式。例如:输入:123456将整数分割成单个字符,然后继续查找组合。该代码将返回以下所有数组。[1,2,3,4,5,6][12,3,4,5,6][1,23,4,5,6][1,2,34,5,6][1,2,3,45,6][1,2,3,4,56][12,34,5,6][12,3,45,6][12,3,4,56][1,23,45,6][1,2,34,56][1,23,4,56][12,34,56][123,4,5,6][1,234,5,6][1,2,345,6][1,2,3,456][123

  9. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  10. ruby - 将数组的内容转换为 int - 2

    我需要读入一个包含数字列表的文件。此代码读取文件并将其放入二维数组中。现在我需要获取数组中所有数字的平均值,但我需要将数组的内容更改为int。有什么想法可以将to_i方法放在哪里吗?ClassTerraindefinitializefile_name@input=IO.readlines(file_name)#readinfile@size=@input[0].to_i@land=[@size]x=1whilex 最佳答案 只需将数组映射为整数:@land边注如果你想得到一条线的平均值,你可以这样做:values=@input[x]

随机推荐