sách gpt4 ai đã đi

swift, UIKit: Làm thế nào tôi có thể chẩn đoán EXC_BAD_INSTRUCTION trong UIKit trên tableView. PerformBatchUpdates()

In lại 作者:行者123 更新时间:2023-11-30 10:31:41 30 4
mua khóa gpt4 Nike

我多年来一直在与 tableView.performBatchUpdates 的 UIKit 问题作斗争。

我有一个简单的数据模型,其中包含由 tableView 和 tableViewCells 驱动的 15 个项目,其中包含 15 个相应的单元格(带回收),其中一个是自定义复选框控件。当单击复选框“打开”时,这 15 个元素中的 7 个将被删除并添加(在中间),然后再次单击“关闭”,重新添加相同的 7 个单元格(在中间)。前 5 个不动。最后 3 个放置在删除/添加的中间 7 个元素之后。

我诊断了数据源和 TableView 的所有更新。首先适当更新数据源,然后在tableView上适当调用deleteRows、insertRows和moveRow。

无需滚动 tableView(同时滚动到 ON 和 OFF 状态)即可正常工作,从而导致我的 7 行通过幻灯片 IN/OUT 动画显示和隐藏。我可以重复多次,并且直到我不将单元格滚动到 View 之外之前它都不会崩溃。

现在,如果我将 tableView 一直向上拖动,直到大多数单元格都被 cellForRow 调用(回收并重新填充),然后使用该复选框,那么我就会在 tableView 上遇到 EXC_BAD_INSTRUCTION 崩溃。 PerformBatchUpdates() 方法(与我的任何代码无关,堆栈跟踪仅在 PerformBatchUpdates() 处结束)。我对此错误做了很多研究,通常它是 NIL 的强制展开,如下所示:Diagnosing EXC_BAD_INSTRUCTION in Swift standard library

问题是:我的单元非常复杂,需要进行大量验证和配置,并且堆栈跟踪不会导致我的任何代码。我还验证了工作状态(首先不滚动到 View 之外)与非工作状态(首先滚动到 View 之外)与performBatchUpdates() 中的deleteRows、addRows 和moveRow 的逻辑没有区别。因此,后续对 cellForRow() 的调用会对单元格执行一些操作,导致 UIKit 对其内容不满意。由于第一次一切正常,它一定与细胞的回收有关,也许还与陈旧的数据有关。

有没有办法可以将 UIKit 源附加到我的项目中,以便我可以看到它正在获取 EXC_BAD_INSTRUCTION?

是否有任何其他符号调试技巧可以用来更好地理解哪些对象与 EXC_BAD_INSTRUCTION 相关?如果我从头开始制作一个示例项目,它可能会正常工作,因此它特定于我的实际单元结构和事件逻辑,这会扰乱 UIKit。

目前,我被迫不使用 tableView 动画(performBatchUpdates()),而只是执行 tableView.reloadData(),直到我弄清楚这一点。

用异常断点捕获异常时的图像:(堆栈跟踪仅上升到performBatchUpdates()本身,在UIKit中,其中或之上没有任何内容)。所以 UIKit 是个异常(exception)。

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

nhập mô tả hình ảnh ở đây

以下是正在发生的所有删除/移动/添加操作的日志:

Hide Fields: 
FORM DELETING: 0, 5
FORM DELETING: 0, 6
FORM DELETING: 0, 7
FORM DELETING: 0, 8
FORM DELETING: 0, 9
FORM DELETING: 0, 10
FORM DELETING: 0, 11
FORM MOVING: [0, 12], to: [0, 5]
FORM MOVING: [0, 14], to: [0, 7]
FORM MOVING: [0, 13], to: [0, 6]

Show Fields:
FORM ADDING: 0, 5
FORM ADDING: 0, 6
FORM ADDING: 0, 7
FORM ADDING: 0, 8
FORM ADDING: 0, 9
FORM ADDING: 0, 10
FORM ADDING: 0, 11
FORM MOVING: [0, 5], to: [0, 12]
FORM MOVING: [0, 7], to: [0, 14]
FORM MOVING: [0, 6], to: [0, 13]

// Elements 0-4 do not move. They stay as the first 5 elements in the tableview

这适用于任意次数迭代的第一次尝试。当我下次第一次将表单完全滚动到 View 之外,然后重试显示/隐藏字段时,此日志保持不变。 (所有相同的日志,但因 EXC_BAD_INSTRUCTION 而崩溃)。这就是为什么我认为它与索引算术无关。

以下是在更新数据模型以反射(reflect)新状态后调用的 PerformBatchUpdates 中的删除、添加和移动逻辑:

tableView.deleteRows(at: toRemove, with: .none)
tableView.insertRows(at: toAdd, with: .none)

for (key, value) in toMove {
print("FORM MOVING: \(key), to: \(value)")
tableView.moveRow(at: key, to: value)
}
// toRemove, toAdd and toMove are populated with indexes you see above.

1 Câu trả lời

深入研究在 cellForRow(atIndexPath...) 中渲染单元格的所有逻辑后,我发现其中一个单元格触发了一个调用链,导致底层数据模型更新,而无需重新加载表格 View 。 (它在 TableView 已经被重新加载的同时替换了数据源中的一项 - 无意中)。

这解释了只有在对底层数据源进行这种不希望的不同步更新之后,我才会在执行下一个 PerformBatchUpdates 操作时发生崩溃。 (或者即使我这样做了:tableView.beginUpdates(), tableView.endUpdates() <-使用相同的 EXC_BAD_INSTRUCTION 也会崩溃)。

因此,在调用 PerformBatchUpdates 或 .beginUpdates()/.endUpdates() 之前,数据源不同步是问题所在。一旦我删除了对数据源的意外更改,performBatchUpdates 就会正常运行和动画 - 只要在它的 block 中数据源更新也与 TableView 上的添加/插入/移动操作相匹配。

由于cellForRow(...)中事件链的复杂性,我花了很长时间才找到

关于 swift ,UIKit : How can I diagnose EXC_BAD_INSTRUCTION in UIKit on tableView. PerformBatchUpdates(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59074565/

30 4 0
行者123
Hồ sơ cá nhân

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá Didi Taxi miễn phí
Mã giảm giá Didi Taxi
Giấy chứng nhận ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com