间歇性崩溃:尝试从更新之前仅包含0行的第0部分中删除第0行

问题描述 投票:0回答:2

我们已经为我们的应用程序实现了滑动以删除功能,但不知怎的,我们看到Crashlytics上的这种间歇性的prod崩溃。

我一直在关注这个崩溃的几个StackOverflow帖子,但我无法得到这次崩溃的确切原因。

我已经尝试多次生成此崩溃但每次都正常工作。

任何想法或想法,如果我在这里做错了什么?以下是崩溃报告和当前正在运行的代码段。

enter image description here

@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)
    }
}
ios swift uitableview swift4.2
2个回答
1
投票

崩溃告诉你发生了什么:当你试图删除它已被删除的行。现在这看起来很奇怪,因为当你提出alertView时,行就在那里。因此,在显示alertView和删除行之间,该行已被其他一些源删除。阅读你的代码显然是可能的。提示警报视图和删除行之间有两个延迟。第一个可能是非常长的时间,直到用户确认删除,第二个是DispatchQueue.main.async,这通常非常快,但仍然可能导致这些类型的错误。

而不是记录要删除的indexPath(因为indexPath可能会在用户确认时更改),而是记录您要删除的项目的ID。当用户最终确认警报时,然后查找它在tableview中的位置并在找到它时将其删除。

更深层次的问题是你有两个事实来源 - tableview和你的数据源,它们不同步。最好先更新数据源,然后让代码自动同步tableview。这样他们总是保持同步。 https://github.com/Instagram/IGListKit是一个已经实现此功能的解决方案,您可以通过使用它获得价值。


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)
    }
}

我希望这段代码有效。

© www.soinside.com 2019 - 2024. All rights reserved.