html转富文本导致UICollectionView闪退问题

问题背景:
我在UICollectionViewCell中将一段html文本转成了NSMutableAttributedString富文本,然后通过UITextView显示出来,从而实现文字中的某段内容可以点击跳转url。
html转成富文本代码如下:

    NSData *data = [htmlStr dataUsingEncoding:NSUnicodeStringEncoding];
    NSMutableAttributedString *aStrContent = [[NSMutableAttributedString alloc] initWithData:data
                                                                                     options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType}
                                                                          documentAttributes:nil
                                                                                       error:nil];
    if (aStrContent.length > 0) {
        [aStrContent addAttribute:NSForegroundColorAttributeName
                            value:RGBAllColor(0x5A6066)
                            range:NSMakeRange(0, aStrContent.length)];
    }
    textView.attributedText = aStrContent;

在计算cell的size时,同样也是先通过上述代码转成富文本后,再计算文本的高度。
在普通的view上通过上述代码展示一段html没有任何问题,但在我的页面滚动时,会偶发以下崩溃:

2021-12-03 16:34:46.597346+0800 GomeEShop[30821:12277281] [CollectionView] An attempt to prepare a layout while a prepareLayout call was already in progress (i.e. reentrant call) has been ignored. Please file a bug. UICollectionView instance is (<GMBCollectionView: 0x7ffdfea2d000; baseClass = UICollectionView; frame = (0 0; 390 760); clipsToBounds = YES; gestureRecognizers = <NSArray: 0x60000e4bb1e0>; layer = <CALayer: 0x60000abd5440>; contentOffset: {0, 1266.3333333333333}; contentSize: {390, 2770.7974196742957}; adjustedContentInset: {0, 0, 50, 0}; layout: <GMFPTGDCollectionViewLayout: 0x7ffd3d6cbd00>; dataSource: <GMFPTGoodsDetailController: 0x7ffe0e2c6a00>>)
2021-12-03 16:34:46.597432+0800 GomeEShop[30821:12277281] [CollectionView] An attempt to update layout information was detected while already in the process of computing the layout (i.e. reentrant call). This will result in unexpected behaviour or a crash. This may happen if a layout pass is triggered while calling out to a delegate. UICollectionViewFlowLayout instance is (<GMFPTGDCollectionViewLayout: 0x7ffd3d6cbd00>)
2021-12-03 16:34:46.616407+0800 GomeEShop[30821:12277281] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndexedSubscript:]: index 3 beyond bounds [0 .. 2]'
*** First throw call stack:
(
0 CoreFoundation 0x00007fff2041daf2 __exceptionPreprocess + 242
1 libobjc.A.dylib 0x00007fff20177e78 objc_exception_throw + 48
2 CoreFoundation 0x00007fff2049a77f _CFThrowFormattedException + 194
3 CoreFoundation 0x00007fff2031c815 -[__NSArrayM removeAllObjects] + 0
4 UIKitCore 0x00007fff23da8a47 -[UICollectionViewFlowLayout _getSizingInfosWithExistingSizingDictionary:] + 1554
5 UIKitCore 0x00007fff23daa64b -[UICollectionViewFlowLayout _fetchItemsInfoForRect:] + 226
6 UIKitCore 0x00007fff23da36ad -[UICollectionViewFlowLayout collectionViewContentSize] + 49
7 GomeEShop 0x00000001082dc5e6 -[GMFPTGDCollectionViewLayout collectionViewContentSize] + 54
8 UIKitCore 0x00007fff23d9b983 -[UICollectionViewData _validateContentSize] + 170
9 UIKitCore 0x00007fff23d9dfc2 __45-[UICollectionViewData validateLayoutInRect:]_block_invoke.126 + 37
10 UIKitCore 0x00007fff23d9c6fc -[UICollectionViewData validateLayoutInRect:] + 405
11 UIKitCore 0x00007fff23d9fa35 -[UICollectionViewData _layoutAttributesForElementsInRect:] + 508
12 UIKitCore 0x00007fff23d9f821 -[UICollectionViewData layoutAttributesForElementsInRect:] + 87
13 UIKitCore 0x00007fff23d66d9a -[UICollectionView _indexPathForItemAtPoint:] + 201
14 UIKitCore 0x00007fff23d66c69 -[UICollectionView indexPathForItemAtPoint:] + 23
15 UIKitCore 0x00007fff240fc885 -[_UICollectionViewMultiSelectController shouldAllowSelectionExtensionAtPoint:] + 81
16 UIKitCore 0x00007fff23e3b6ef -[UIMultiSelectInteraction gestureRecognizer:shouldReceiveTouch:] + 181
17 UIKitCore 0x00007fff241b5f2d -[UIGestureRecognizer _shouldReceiveTouch:forEvent:recognizerView:] + 1387
18 UIKitCore 0x00007fff247063ea __72-[UITouchesEvent _addGestureRecognizersForView:toTouch:forContinuation:]_block_invoke + 350
19 UIKitCore 0x00007fff24705ddf __62-[UITouchesEvent _collectGestureRecognizersForView:withBlock:]_block_invoke + 502
20 UIKitCore 0x00007fff2470572f -[UITouchesEvent _collectGestureRecognizersForView:withBlock:] + 304
21 UIKitCore 0x00007fff2470625c -[UITouchesEvent _addGestureRecognizersForView:toTouch:forContinuation:] + 149
22 UIKitCore 0x00007fff24706169 -[UITouchesEvent _addGestureRecognizersForView:toTouch:] + 53
23 UIKitCore 0x00007fff247067a2 -[UITouchesEvent _addTouch:forDelayedDelivery:] + 878
24 UIKitCore 0x00007fff2471e725 _AddTouchToEventAndDetermineIfNeedsCancel + 328
25 UIKitCore 0x00007fff2471eb14 ____updateTouchesWithDigitizerEventAndDetermineIfShouldSend_block_invoke.100 + 125
26 CoreFoundation 0x00007fff203779d3 NSDICTIONARY_IS_CALLING_OUT_TO_A_BLOCK + 7
27 CoreFoundation 0x00007fff20377f3f ____NSDictionaryEnumerate_block_invoke.11 + 50
28 CoreFoundation 0x00007fff20453bad CFBasicHashApply + 117
29 CoreFoundation 0x00007fff20377af3 __NSDictionaryEnumerate + 183
30 UIKitCore 0x00007fff24723c94 __processEventQueue + 12095
31 UIKitCore 0x00007fff2471ad0f __eventFetcherSourceCallback + 104
32 CoreFoundation 0x00007fff2038c37a CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17
33 CoreFoundation 0x00007fff2038c272 __CFRunLoopDoSource0 + 180
34 CoreFoundation 0x00007fff2038b7b6 __CFRunLoopDoSources0 + 346
35 CoreFoundation 0x00007fff20385f1f __CFRunLoopRun + 878
36 CoreFoundation 0x00007fff203856c6 CFRunLoopRunSpecific + 567
37 UIFoundation 0x00007fff23a48af4 -[NSHTMLReader _loadUsingWebKit] + 1847
38 UIFoundation 0x00007fff23a49a29 -[NSHTMLReader attributedString] + 22
39 UIFoundation 0x00007fff239ca839 NSReadAttributedStringFromURLOrData + 9439
40 UIFoundation 0x00007fff239c82e5 -[NSAttributedString(NSAttributedStringUIFoundationAdditions) initWithData:options:documentAttributes:error:] + 144
41 GomeEShop 0x0000000108355130 +[GMFPTGDPromTextCell promAttributeString:] + 240
42 GomeEShop 0x0000000108355644 +[GMFPTGDPromTextCell sizeWithModel:] + 372
43 CoreFoundation 0x00007fff204242fc invoking
+ 140
44 CoreFoundation 0x00007fff204217b2 -[NSInvocation invoke] + 303
45 CoreFoundation 0x00007fff20421a43 -[NSInvocation invokeWithTarget:] + 70
46 GomeEShop 0x00000001081c1c3b +[NSObject(GMulArgPerformSel) gm_target:performSel:arguments:] + 1019
47 GomeEShop 0x000000010844ad0c -[GMFPTGoodsDetailController collectionView:layout:sizeForItemAtIndexPath:] + 748
48 UIKitCore 0x00007fff23da8ebd -[UICollectionViewFlowLayout _getSizingInfosWithExistingSizingDictionary:] + 2696
49 UIKitCore 0x00007fff23daa64b -[UICollectionViewFlowLayout _fetchItemsInfoForRect:] + 226
50 UIKitCore 0x00007fff23da312a -[UICollectionViewFlowLayout prepareLayout] + 246
51 GomeEShop 0x00000001082dc899 -[GMFPTGDCollectionViewLayout prepareLayout] + 57
52 UIKitCore 0x00007fff23d9bb0a -[UICollectionViewData _prepareToLoadData] + 268
53 UIKitCore 0x00007fff23d9c59c -[UICollectionViewData validateLayoutInRect:] + 53
54 UIKitCore 0x00007fff23d61591 -[UICollectionView layoutSubviews] + 240
55 UIKitCore 0x00007fff24bd750c -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2924
56 QuartzCore 0x00007fff27a7718f -[CALayer layoutSublayers] + 258
57 QuartzCore 0x00007fff27a7d641 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 575
58 QuartzCore 0x00007fff27a89399 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 65
59 QuartzCore 0x00007fff279c9114 _ZN2CA7Context18commit_transactionEPNS_11TransactionEdPd + 496
60 QuartzCore 0x00007fff279ffeaf _ZN2CA11Transaction6commitEv + 783
61 QuartzCore 0x00007fff27a0106b _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 79
62 CoreFoundation 0x00007fff2038b1e8 CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 23
63 CoreFoundation 0x00007fff20385a67 __CFRunLoopDoObservers + 547
64 CoreFoundation 0x00007fff2038600a __CFRunLoopRun + 1113
65 CoreFoundation 0x00007fff203856c6 CFRunLoopRunSpecific + 567
66 GraphicsServices 0x00007fff2b76adb3 GSEventRunModal + 139
67 UIKitCore 0x00007fff24675187 -[UIApplication _run] + 912
68 UIKitCore 0x00007fff2467a038 UIApplicationMain + 101
69 GomeEShop 0x00000001071cc9f0 main + 112
70 libdyld.dylib 0x00007fff20256409 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndexedSubscript:]: index 3 beyond bounds [0 .. 2]'
terminating with uncaught exception of type NSException
CoreSimulator 776.3 - Device: iPhone 12 (E58EF578-151D-40C6-ACBC-1C0D3307D6A1) - Runtime: iOS 14.2 (18B79) - DeviceType: iPhone 12
CUICatalog: Invalid asset name supplied: ''
(lldb)

开始排查问题时,我的关注点一直在collectionViewContentSize上,但一直没有找出问题,后来发现屏蔽该cell数据时不会有问题,定位到问题之后,在网上也看到了类似问题,原来是html转富文本的过程比较耗时,频繁刷新调用时会导致主线程卡死,最终导致闪退。
解决方案:
提前处理数据,在拿到接口数据初始化model时,就进行转换操作,这样只要数据不发生变化,就不会重新进行处理了。

@implementation GMMPTGDPromInfo

- (void)setPromDesc:(NSString *)promDesc {
    if ([_promDesc isEqualToString:promDesc]) {
        return;
    }
    _promDesc = promDesc;
    
    // 因为html转富文本时比较耗内存,滚动列表时多次转换处理 会导致主线程卡顿等问题,所以在model初始化时就转换后,在ui绘制时直接用
    if (GMK_Str_Not_Valid(promDesc)) {
        self.attributePromDesc = nil;
        return;
    }
    NSString *htmlStr = [NSString gmTransHTMLStringNewLineCharacter:promDesc];
    if (GMK_Str_Not_Valid(htmlStr))
    {
        self.attributePromDesc = nil;
        return;
    }
    NSData *data = [htmlStr dataUsingEncoding:NSUnicodeStringEncoding];
    NSMutableAttributedString *aStrContent = [[NSMutableAttributedString alloc] initWithData:data
                                                                                     options:@{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType}
                                                                          documentAttributes:nil
                                                                                       error:nil];
    if (aStrContent.length > 0) {
        [aStrContent addAttribute:NSForegroundColorAttributeName
                            value:RGBAllColor(0x5A6066)
                            range:NSMakeRange(0, aStrContent.length)];
    }
    self.attributePromDesc = aStrContent;
}

@end

至此问题解决,同样的道理,在UITableview中应该也会出现相同问题。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,657评论 6 505
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,889评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,057评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,509评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,562评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,443评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,251评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,129评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,561评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,779评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,902评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,621评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,220评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,838评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,971评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,025评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,843评论 2 354

推荐阅读更多精彩内容

  • 首先如果遇到应用卡顿或者因为内存占用过多时一般使用Instruments里的来进行检测。但对于复杂情况可能就需要用...
    攻克乃还_阅读 1,845评论 0 7
  • Xcode 中的调试技巧与我们的日常开发息息相关,而这些调试技巧在我们解决Bug时,常常有事半功倍的作用,经常会用...
    咖啡绿茶1991阅读 459评论 0 1
  • 一、常用的命令一、常用的命令 1.print、po输出打印 打印变量的值可以使用print(简写p)命令,该命令如...
    大象_cf34阅读 2,376评论 0 0
  • 关键时刻,第一时间送达! 问题种类 时间复杂度 在集合里数据量小的情况下时间复杂度对于性能的影响看起来微乎其微。但...
    C9090阅读 893评论 0 1
  • 2018-02-06 11:51:11.531096+0800 ZYB[1446:442478] selected...
    风雪山神喵阅读 496评论 0 0