UITableView的开始/结束更新在不同的tableView上崩溃

时间:2019-06-19 08:25:36

标签: swift multithreading uitableview timer crash

我的项目具有mainFeed tableViewController,并且如果我选择任何行,它将打开另一个具有不同行数的tableViewController。计时器1.0秒后在secondTableViewController内,我调用了beginUpdates,endUpdates链,如果我始终停留在secondTableViewVC中,一切正常,更新成功结束。 但是,如果计时器结束后,更新链开始(需要一些时间),并且如果用户在导航上按“后退”以在链尚未完成时返回mainFeed tableViewController,则链开始/结束更新将从secondVC结束,已经关闭,并且我目前在mainVC中崩溃,并显示错误:更新后的行数应等于更新前的行数。但是我什至不删除secondVC内的任何行,我用它来更新里面带有wkwebview的单元格的高度。

因此,在这种情况下,逻辑应该在secondVC上结束并在我关闭它后停止工作,这会影响我的firstVC并使它崩溃。 当用户返回时,我试图使计时器无效,但仅在开始/结束更新尚未开始时,该计时器才起作用。

我试图弄清楚我错过了什么,做错了什么。关于如何打破这一链条的任何想法?

我的猜测是什么开始/结束更新在另一个线程中起作用,但是我不直接在另一个线程中调用它。 就目前而言,我有一个解决办法,如果更新开始且尚未完成,用户将无法返回,但是我不认为这是一个好的解决方案。

首先,当单元格中的wkwebview完成时

self.timer = Timer.scheduledTimer(timeInterval: 1.0,
                                          target: self,
                                          selector: #selector(self.updateHeightCell),
                                          userInfo: nil,
                                          repeats: false)

然后我将委托rootViewController中的webDidLoadWithContentHeight称为secondVC。

@objc private func updateHeightCell() {
    self.height = self.webView.scrollView.contentSize.height * 1.2
    self.rootViewController.webDidLoadWithContentHeight(self.height,     currentWebScrollPosition: scrollPositionBeforeLoadFinish)
    self.webView.scrollView.isScrollEnabled = false
    }
    func webDidLoadWithContentHeight(_ height: CGFloat, currentWebScrollPosition: CGFloat) {
        webCellIsLoaded = true
        self.tableView.beginUpdates()
        self.webContentHeight = height
        self.tableView.endUpdates()
        self.webCellReloadedCount += 1
        self.tableView.contentOffset.y = currentWebScrollPosition
        self.setupMaterialBarAlphaIfNecessary()
        self.tableView.isScrollEnabled = true
    }

返回按钮

    override func didMaterialBackButtonTouch() {
        // stop webView
        let cells = tableView.visibleCells
        for cell in cells {
            if (cell.isKind(of: MaterialViewCell3.self)) {
                let webCell = cell as! MaterialViewCell3
                webCell.webView.stopLoading()
                webCell.timer?.invalidate()
            }
        }

        self.viewModel.avoidViewController()
        guard let source = self.source else {
            fatalError("\n[\(self) didMaterialBackButtonTouch] no source view controller!\n")
        }
        switch source {
        case .myFeed:
            self.performSegue(withIdentifier: String.unwindFromMaterialToMyFeedSegueID, sender: self)
        case .mainFeed:
            self.performSegue(withIdentifier: String.unwindFromMaterialToMainFeedSegueID, sender: self)
}
}

预期结果是,当用户回退在secondVC中调用的开始/结束更新时,不会影响mainVC。

0 个答案:

没有答案