在用户升级到iOS 9之后,我们注意到了一系列坏访问(EXC_BAD_ACCESS
)崩溃,这些崩溃不会出现在仍然在iOS 8上的用户身上,当我们在UITableView上调用endUpdates
时就会发生这种情况。
崩溃日志包括以下原因:
在当前参数寄存器中找到的选择器名称: numberOfRowsInSection: 在当前参数寄存器中找到的选择器名称: indexPathForRowAtGlobalRow:
堆栈跟踪#1:
1 UIKit __46-[UITableView _updateWithItems:updateSupport:]_block_invoke + 92
2 UIKit __46-[UITableView _updateWithItems:updateSupport:]_block_invoke1007 + 224
3 UIKit -[UITableView _updateWithItems:updateSupport:] + 2556
4 UIKit -[UITableView _endCellAnimationsWithContext:] + 12892
[...]
堆栈跟踪#2:
1 UIKit __46-[UITableView _updateWithItems:updateSupport:]_block_invoke + 100
2 UIKit -[UITableViewRowData globalRowForRowAtIndexPath:] + 102
3 UIKit __46-[UITableView _updateWithItems:updateSupport:]_block_invoke1007 + 182
4 UIKit -[UITableView _updateWithItems:updateSupport:] + 2300
5 UIKit -[UITableView _endCellAnimationsWithContext:] + 10552
我们能够复制这个问题,但不知道如何解决这个问题。
发布于 2015-12-23 13:53:45
当您的iOS9中没有导致endUpdates与EXC_BAD_ACCESS崩溃的行时,似乎在EXC_BAD_ACCESS中出现了一个bug。要解决这个问题,您必须在调用tableView reloadData之前调用beginUpdates。
从克劳迪奥·雷迪指向我的线程:)在第1节插入中,在调用[tableView beginUpdates];
之前,我已经实现了以下解决方法
if ([[NSProcessInfo processInfo] operatingSystemVersion].majorVersion >= 9)
{
// there's a bug in iOS9 when your UITableView has no rows that causes endUpdates to crash with EXC_BAD_ACCESS
// to work around this bug, you have to call tableView reloadData before calling beginUpdates.
BOOL shouldReloadData = YES;
NSInteger numberOfSections = [tableView.dataSource numberOfSectionsInTableView:tableView];
for (NSInteger section = 0; section < numberOfSections; section++)
{
if ([tableView.dataSource tableView:tableView numberOfRowsInSection:section] > 0)
{
// found a row in current section, do not need to reload data
shouldReloadData = NO;
break;
}
}
if (shouldReloadData)
{
[tableView reloadData];
}
}
发布于 2019-03-28 10:05:33
我也面临着这个问题,上面在表视图上调用reloadData()
的答案确实解决了这个问题,但是这并不理想,因为由于重新加载,与更新相关的动画并不流畅。
问题的根源在于,在调用方法时,我在表视图上以编程方式调用了selectRow(at indexPath: IndexPath?, animated: Bool, scrollPosition: UITableView.ScrollPosition)
,这是一个无效的索引路径。(表视图中的更新用于展开/折叠一个区段,以显示行在或零行内,有时我会在折叠部分中选择一行)。这种行为在为表视图中不可见的索引路径选择行时不会造成崩溃,但是当在beginUpdates(
之间更新endUpdates()
调用和在选择无效的索引路径之后更新endUpdates()
调用时,在endUpdates()
调用时会出现EXC_BAD_ACCESS崩溃。在调用selectRowAt:
之前添加一个检查,以确保索引路径是可见的/有效的,然后以编程方式选择解决了崩溃,而不需要调用reloadData()
发布于 2019-03-29 09:57:34
在尝试执行beginUpdates()和endUpdates()调用之间的多个插入、删除或重新加载操作时,我遇到了此错误,如下所示
tableView.beginUpdates()
tableView.deleteRows(at: [deletePaths], with: .fade)
tableView.insertRows(at: [insertPaths], with: .fade)
tableView.endUpdates()
我通过打电话解决了这个问题
performBatchUpdates(_ updates: (() -> Void)?, completion: ((Bool) -> Void)? = nil)
而不是使用开始和结束调用,例如。
self.tableView.performBatchUpdates({
self.tableView.deleteRows(at: [deletePaths], with: .fade)
self.tableView.insertRows(at: [insertPaths], with: .fade)
}, completion: nil)
https://stackoverflow.com/questions/34443185
复制