You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

自定义SelfSizedTableView调用reloadData()崩溃问题求助

自定义SelfSizedTableView调用reloadData()崩溃的原因与解决办法

崩溃原因

从崩溃堆栈和自定义TableView代码来看,核心问题是布局操作的递归死循环:

  1. 在reloadData()中调用layoutIfNeeded()会立即触发TableView的同步布局,包括cell创建、约束更新等操作。
  2. 布局过程中系统会读取intrinsicContentSize,而该属性的getter里又调用了setNeedsLayout()和layoutIfNeeded(),再次触发布局流程。
  3. 这种循环会导致AutoLayout引擎(NSISEngine)反复尝试更新约束、插入布局变量,最终引发CoreAutoLayout内部的对象表操作异常,导致崩溃。

从堆栈可以看到,崩溃发生在TableView配置cell、更新可见cell的过程中,正是布局循环触发的关键节点。

解决办法

针对自定义TableView代码,需要修改两处核心逻辑打破布局循环:

修改1:重构reloadData方法

移除同步布局调用layoutIfNeeded(),只保留标记intrinsicContentSize需要更新的操作,让系统在合适时机异步处理布局:

open override func reloadData() {
    super.reloadData()
    invalidateIntrinsicContentSize()
}

修改2:修正intrinsicContentSize的实现

intrinsicContentSize的getter应该是纯计算属性,不能触发布局操作(setNeedsLayout/layoutIfNeeded),正确实现只返回当前contentSize即可:

open override var intrinsicContentSize: CGSize {
    return CGSize(
        width: contentSize.width,
        height: contentSize.height
    )
}

可选优化:补充布局更新触发

如果需要确保contentSize变更时及时更新intrinsicContentSize,可以在layoutSubviews中补充标记:

open override func layoutSubviews() {
    super.layoutSubviews()
    invalidateIntrinsicContentSize()
}

修改后,系统会在当前runloop结束后处理布局和intrinsicContentSize的更新,避免同步触发的循环问题。

原代码与崩溃堆栈

自定义SelfSizedTableView原代码

import UIKit

open class SelfSizedTableView: UITableView {
    open override func reloadData() {
        super.reloadData()
        self.invalidateIntrinsicContentSize()
        self.layoutIfNeeded()
    }

    open override var intrinsicContentSize: CGSize {
        setNeedsLayout()
        layoutIfNeeded()
        return CGSize(
            width: contentSize.width,
            height: contentSize.height
        )
    }
}

崩溃堆栈信息

Crashed: com.apple.main-thread
0  CoreAutoLayout                 0x17d38 object_table_insert_and_return_old_value_if_replaced + 96
1  CoreAutoLayout                 0x8324 NSISObjectTableInsert + 72
2  CoreAutoLayout                 0x80b0 -[NSISEngine startObservingChangesForVariable:] + 76
3  UIKitCore                      0x373e2c _UILayoutItemSetUpVariableObservation + 144
4  UIKitCore                      0x2aae18 _UILayoutItemCreateAndObserveVariableWithValueRestriction + 104
5  UIKitCore                      0x518fc4 -[UIView nsli_boundsWidthVariable] + 48
6  UIKitCore                      0x34b7e8 -[UIView(AdditionalLayoutSupport) nsli_lowerAttribute:intoExpression:withCoefficient:forConstraint:onBehalfOfLayoutGuide:] + 2860
7  UIKitCore                      0x566e50 -[UIView(AdditionalLayoutSupport) nsli_lowerAttribute:intoExpression:withCoefficient:forConstraint:] + 316
8  CoreAutoLayout                 0xbb50 -[NSLayoutConstraint _lowerIntoExpression:reportingConstantIsRounded:] + 76
9  CoreAutoLayout                 0xdee8 -[NSLayoutConstraint _addToEngine:mutuallyExclusiveConstraints:] + 136
10 UIKitCore                      0x1cd270 __57-[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:]_block_invoke_2 + 368
11 CoreAutoLayout                 0x7bac -[NSISEngine withBehaviors:performModifications:] + 80
12 UIKitCore                      0x1badd0 __57-[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:]_block_invoke + 528
13 UIKitCore                      0x3980f4 -[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:] + 188
14 UIKitCore                      0x1cd1b8 __57-[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:]_block_invoke_2 + 184
15 CoreAutoLayout                 0x7bac -[NSISEngine withBehaviors:performModifications:] + 80
16 UIKitCore                      0x1badd0 __57-[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:]_block_invoke + 528
17 UIKitCore                      0x3980f4 -[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:] + 188
18 UIKitCore                      0x1cd1b8 __57-[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:]_block_invoke_2 + 184
19 CoreAutoLayout                 0x7bac -[NSISEngine withBehaviors:performModifications:] + 80
20 UIKitCore                      0x1badd0 __57-[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:]_block_invoke + 528
21 UIKitCore                      0x3980f4 -[UIView(AdditionalLayoutSupport) _switchToLayoutEngine:] + 188
22 UIKitCore                      0x45ae68 -[UIView(AdditionalLayoutSupport) _initializeHostedLayoutEngine] + 208
23 UIKitCore                      0x1da868 -[UIView _layoutEngine_windowDidChange] + 120
24 UIKitCore                      0x29ebbc -[UIView(Internal) _didMoveFromWindow:toWindow:] + 276
25 UIKitCore                      0x29ee48 -[UIView(Internal) _didMoveFromWindow:toWindow:] + 928
26 UIKitCore                      0x1cb998 __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 136
27 CoreAutoLayout                 0x7bac -[NSISEngine withBehaviors:performModifications:] + 80
28 UIKitCore                      0x2576e4 -[UIView(Hierarchy) _postMovedFromSuperview:] + 780
29 UIKitCore                      0x179ca4 -[UIView(Internal) _addSubview:positioned:relativeTo:] + 2148
30 UIKitCore                      0x38ec30 -[UITableView _addSubview:positioned:relativeTo:] + 104
31 UIKitCore                      0x168d68 -[UIScrollView _addContentSubview:atBack:] + 376
32 UIKitCore                      0x18d4e8 -[UITableView _addContentSubview:atBack:] + 248
33 UIKitCore                      0x189e70 __53-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke + 1744
34 UIKitCore                      0x1632d0 +[UIView(Animation) performWithoutAnimation:] + 96
35 UIKitCore                      0x3f4664 -[UITableView _configureCellForDisplay:forIndexPath:] + 244
36 UIKitCore                      0x27010c -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 1916
37 UIKitCore                      0x45a858 -[UITableView _updateVisibleCellsForRanges:createIfNecessary:] + 700
38 UIKitCore                      0x293f04 -[UITableView _updateVisibleCellsNow:] + 1464
39 UIKitCore                      0x16c484 -[UITableView layoutSubviews] + 436
40 UIKitCore                      0x17c1d0 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2556
41 QuartzCore                     0x3d520 CA::Layer::layout_if_needed(CA::Transaction*) + 528
42 UIKitCore                      0x1dd8b0 -[UIView(Hierarchy) layoutBelowIfNeeded] + 556
43 Drops                          0x78e68 SelfSizedTableView.reloadData() + 15 (SelfSizedTableView.swift:15)
44 Drops                          0x78eb8 @objc SelfSizedTableView.reloadData() + 4365668024 (<compiler-generated>:4365668024)
45 UIKitCore                      0x16c300 -[UITableView layoutSubviews] + 48
46 UIKitCore                      0x17c1d0 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 2556
47 QuartzCore                     0x3d520 CA::Layer::layout_if_needed(CA::Transaction*) + 528
48 UIKitCore                      0x1dd8b0 -[UIView(Hierarchy) layoutBelowIfNeeded] + 556
49 Drops                          0x78f6c SelfSizedTableView.intrinsicContentSize.getter + 19 (SelfSizedTableView.swift:19)
50 Drops                          0x78ef4 @objc SelfSizedTableView.intrinsicContentSize.getter + 4365668084 (<compiler-generated>:4365668084)
51 UIKitCore                      0x19cae8 -[UIView _generateContentSizeConstraints] + 56
52 UIKitCore                      0x24beac -[UIView _updateContentSizeConstraints] + 268
53 UIKitCore                      0x2f6440 -[UIView(AdditionalLayoutSupport) _updateSystemConstraints] + 124
54 UIKitCore                      0x35aaac -[UIView(AdditionalLayoutSupport) _sendUpdateConstraintsIfNecessaryForSecondPass:] + 480
55 UIKitCore                      0x17f5a0 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededCollectingViews:forSecondPass:] + 996
56 UIKitCore                      0x17f480 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededCollectingViews:forSecondPass:] + 708
57 UIKitCore                      0x17f480 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededCollectingViews:forSecondPass:] + 708
58 CoreAutoLayout                 0x7bac -[NSISEngine withBehaviors:performModifications:] + 80
59 UIKitCore                      0x4f6720 -[UIView(AdditionalLayoutSupport) _recursiveUpdateConstraintsIfNeededCollectingViews:forSecondPass:] + 120
60 UIKitCore                      0x17f480 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededCollectingViews:forSecondPass:] + 708
61 UIKitCore                      0x1e494c __100-[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededWithViewForVariableChangeNotifications:]_block_invoke + 84
62 UIKitCore                      0x25c954 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededWithViewForVariableChangeNotifications:] + 160
63 UIKitCore                      0x314fd8 -[UIView(AdditionalLayoutSupport) _systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority:hasIntentionallyCollapsedHeight:] + 224
64 UIKitCore                      0x272668 -[UITableViewCell systemLayoutSizeFittingSize:withHorizontalFittingPriority:verticalFittingPriority:] + 656
65 UIKitCore                      0x331148 -[UITableView _heightForCell:atIndexPath:] + 400
66 UIKitCore                      0x18a120 __53-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke + 2432
67 UIKitCore                      0x1632d0 +[UIView(Animation) performWithoutAnimation:] + 96
68 UIKitCore                      0x3f4664 -[UITableView _configureCellForDisplay:forIndexPath:] + 244
69 UIKitCore                      0x27010c -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 1916
70 UIKitCore                      0x44a10c -[UITableView _createPreparedCellForRowAtIndexPath:willDisplay:] + 88
71 UIKitCore                      0x534d90 -[UITableView _heightForRowAtIndexPath:] + 152
72 UIKitCore                      0x1cab54 -[UISectionRowData heightForRow:inSection:canGuess:] + 208
73 UIKitCore                      0x16ee8c -[UITableViewRowData heightForRow:inSection:canGuess:adjustForReorderedRow:] + 252
74 UIKitCore                      0x237c54 -[UITableViewRowData rectForRow:inSection:heightCanBeGuessed:] + 332
75 UIKitCore                      0x16c890 -[UITableViewRowData rectForGlobalRow:heightCanBeGuessed:] + 108
76 UIKitCore                      0x277eb0 -[UITableView _prefetchCellAtGlobalRow:aboveVisibleRange:] + 264
77 UIKitCore                      0x1c52f4 __48-[UITableView _configureCellPrefetchingHandlers]_block_invoke + 56
78 UIKitCore                      0x170804 -[_UITableViewPrefetchContext updateVisibleIndexRange:withContentOffset:] + 2392
79 UIKitCore                      0x42db08 -[UITableView _updateCycleIdleUntil:] + 188
80 UIKitCore                      0x17e2b8 ___UIUpdateCycleNotifyIdle_block_invoke + 704
81 libdispatch.dylib              0x63094 _dispatch_call_block_and_release + 24
82 libdispatch.dylib              0x64094 _dispatch_client_callout + 16
83 libdispatch.dylib              0x45858 _dispatch_main_queue_drain + 888
84 libdispatch.dylib              0x454d0 _dispatch_main_queue_callback_4CF$VARIANT$armv81 + 36
85 CoreFoundation                 0x4e0d4 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
86 CoreFoundation                 0xb5f8 __CFRunLoopRun + 2544
87 CoreFoundation                 0x1e250 CFRunLoopRunSpecific + 572
88 GraphicsServices               0x1988 GSEventRunModal + 160
89 UIKitCore                      0x4e5a94 -[UIApplication _run] + 1080
90 UIKitCore                      0x27efd4 UIApplicationMain + 336
91 libswiftUIKit.dylib            0x27ee4 UIApplicationMain(_:_:_:_:) + 100
92 Drops                          0x1249a0 static UIApplicationDelegate.main() + 4366371232 (<compiler-generated>:4366371232)
93 Drops                          0x124928 static AppDelegate.$main() + 25 (<compiler-generated>:25)
94 Drops                          0x1263e8 main + 26 (AppDelegate.swift:26)
95 ???                            0x1036b44d0 (Missing)

内容的提问来源于stack exchange,提问作者Mohamed Mostafa Fawzi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 05:25:36