用户升级到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
我们能够重新解决这个问题,但是没有任何关于如何修复它的线索。
答案 0 :(得分:8)
当您的UITableView没有导致endUpdates与EXC_BAD_ACCESS崩溃的行时,看起来iOS9中存在一个错误。要解决此错误,您必须在调用beginUpdates之前调用tableView reloadData。
从Claudio Redi指示我的帖子iOS9 iPad UITableView Crash (EXC_BAD_ACCESS) on 1st section insert,我已经实施了您在调用[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];
}
}
答案 1 :(得分:1)
当我尝试在beginUpdates()和endUpdates()调用之间执行多个插入,删除或重载操作时,遇到了此错误,
AWS_STORAGE_BUCKET_NAME = env.str('AWS_STORAGE_BUCKET_NAME')
AWS_S3_CUSTOM_DOMAIN = '%s.s3.amazonaws.com' % AWS_STORAGE_BUCKET_NAME
我能够通过致电
解决此问题tableView.beginUpdates()
tableView.deleteRows(at: [deletePaths], with: .fade)
tableView.insertRows(at: [insertPaths], with: .fade)
tableView.endUpdates()
例如,而不是使用开始和结束调用。
performBatchUpdates(_ updates: (() -> Void)?, completion: ((Bool) -> Void)? = nil)
答案 2 :(得分:0)
我也遇到了这个问题,上面在表视图上调用reloadData()
的答案确实解决了这个问题,但这并不理想,因为与更新相关联的动画由于重新加载而不稳定
问题的根源是我在表视图上以编程方式调用了selectRow(at indexPath: IndexPath?, animated: Bool, scrollPosition: UITableView.ScrollPosition)
,因为在调用该方法时索引路径无效。 (表视图中的更新是展开/折叠部分以显示其中的行或零行,我有时会在折叠部分中选择一行)。当为表视图中不可见的索引路径选择一行时,但在选择了一个UITableView
和beginUpdates(
之间的endUpdates()
调用之后,此行为不会导致崩溃索引路径无效,则endUpdates()
调用时EXC_BAD_ACCESS会崩溃。在调用selectRowAt:
之前添加检查以确保索引路径可见/有效,然后以编程方式选择解决了崩溃,而无需调用reloadData()