我们已为应用实现了滑动删除功能,但是不知何故,我们在Crashlytics上看到了这种间歇性的产品崩溃。
我一直在关注有关该崩溃的StackOverflow帖子,但是我无法找到导致崩溃的确切原因。
我曾多次尝试产生此崩溃,但每次都能正常工作。
任何想法或想法,如果我在这里做错了吗?下面是崩溃报告和当前正在运行的代码段。
@available(iOS 11.0, *)
private func actionForType(alertID: String, swipeAction: AlertSwipeActionType, indexPath: IndexPath) -> UIContextualAction {
let contexualAction = UIContextualAction(style: .normal, title: nil) { [weak self] (action, view, completion) in
guard let strongSelf = self else {
return
}
switch swipeAction {
......
case .affirm:
completion(true)
strongSelf.dispositionAlert(id: alertID, status: true, indexPath: indexPath)
......
}
}
......
return contexualAction
}
fileprivate func dispositionAlert(id: String, status: Bool, indexPath: IndexPath) {
let dispositionRequest = AlertDispositionUpdateBody(id: id, disposition: status, questionId: nil)
self.updateAlertDispositionStatus(request: dispositionRequest) { [weak self] in
guard let strongSelf = self else {
return
}
strongSelf.removeCellWithAnimationAt(indexPath: indexPath)
strongSelf.loadAlerts()
}
}
fileprivate func removeCellWithAnimationAt(indexPath: IndexPath) {
DispatchQueue.main.async {
self.tableView.beginUpdates() // likely not required
self.removeAlertAtIndexPath(indexPath)
self.tableView.deleteRows(at: [indexPath], with: .fade)
self.tableView.endUpdates() // likely not required either
}
}
@objc func loadAlerts() {
self.startLoadingAnimation()
self.alertsFooterList.removeAll()
AlertsManager.sharedInstance.loadMemberAlerts()
}
fileprivate func removeAlertAtIndexPath(_ indexPath: IndexPath) {
let alertStatus = self.alertTabType.statusToLoad[indexPath.section]
if let alerts = self.alertsList[alertStatus],
alerts.count > indexPath.row {
self.alertsList[alertStatus]?.remove(at: indexPath.row)
}
}
答案 0 :(得分:1)
当机事件告诉您发生了什么:尝试删除该行时,该行已被删除。现在这似乎很奇怪,因为当您显示alertView时,该行在那里。因此,在显示alertView和删除行之间,该行已被其他来源删除。阅读您的代码显然是可能的。在显示警报视图和删除行之间有两个延迟。第一个可能是很长的时间,直到用户确认删除为止,第二个是DispatchQueue.main.async
,通常速度很快,但仍会导致这些类型的错误。
而不是记录要删除的indexPath(因为在用户确认时indexPath可能已更改),而是记录您要删除的项目的ID。当用户最终确认警报后,然后在表视图中查找警报,如果找到,则将其删除。
更深层的问题是,您有两个事实来源-tableview和您的数据源,并且它们不同步。最好先更新您的数据源,然后再添加可自动同步表视图的代码。这样,它们始终保持同步。 https://github.com/Instagram/IGListKit是已经实现此目标的解决方案,您可能会通过使用它来获取价值。
答案 1 :(得分:0)
如果使用tableview删除调用的行,则该部分的第一个调用号。 下面的代码。
代码: swift
fileprivate func removeCellWithAnimationAt(indexPath: IndexPath) {
DispatchQueue.main.async {
self.removeAlertAtIndexPath(indexPath)
self.tableView.numberOfRows(inSection: indexPath.section) // called first
self.tableView.deleteRows(at: [indexPath], with: .fade)
}
}
我希望这段代码能奏效。