简体   繁体   English

iOS:无效更新:第 0 节中的行数无效

[英]iOS: Invalid update: invalid number of rows in section 0

I create a table view that every time I scroll to the end of table it will show shimmer in table section 1 for waiting the api load a new data.我创建了一个表格视图,每次滚动到表格末尾时,它都会在表格第 1 部分显示微光,等待 api 加载新数据。 After api finish load data, new data will append to the array that use for contain all data that be show to table view on section 0, then reload the table view to update the section 1 numberOfRowsInSection to 0 to hide the shimmer and update the section 0 numberOfRowsInSection api 完成加载数据后,新数据将 append 到用于包含在第 0 节上显示到表视图的所有数据的数组中,然后重新加载表视图以将第 1 节 numberOfRowsInSection 更新为 0 以隐藏闪光并更新节0 numberOfRowsInSection

So this is the example of my code所以这是我的代码示例

fileprivate var data = [dataArray]() {
        didSet {
            guard !data.isEmpty else {
                return
            }
            tableView.reloadData()
            tableView.layoutIfNeeded()
            view.layoutIfNeeded()
        }
    }

fileprivate var isLoadingMore: Bool = false {
        didSet {
            tableView.reloadSections(IndexSet(integer: 1), with: .automatic)
            tableView.layoutIfNeeded()
            tableViewHeightConstraint.constant = tableView.contentSize.height + 60.0
            view.layoutIfNeeded()
        }
    }

fileprivate func loadData() {
        if let size = self.paging.totalSize,
            data.count >= size {
                return
        }

        let limit = paging.limit
        let offset =  paging.offset

        guard !isLoadingMore else { return }

        isLoadingMore = true
        controller.requestContent(
            completion: { [weak self] (success, offset, size, data) in
                DispatchQueue.main.async {
                    self?.isLoadingMore = false

                    guard let list = data,
                        let data = list as? [dataArray],
                        let size = size else {
                            return
                    }

                    if success {
                        if self?.paging.currentPage == 0 {
                            self?.data = data

                            if self?.scrollView.frame.size.height >= self?.scrollView.contentSize.height {
                                self?.paging.totalSize = size
                                self?.paging.currentPage += 1
                                self?.loadData()
                                return
                            }
                        } else {
                            self?.data.append(contentsOf: songs)
                        }
                        self?.paging.totalSize = size
                        self?.paging.currentPage += 1
                    } else {
                        self?.alert("failed")
                    }
                }
        })
    }

fileprivate func loadDataFromCoreData() {
        isLoadingMore = false

        let context = (UIApplication.shared.delegate as! AppDelegate).managedObjectContext
        let dataFromCoreData = Datas.fetchData(context: context).filter({$0.isSaved})

        songs = dataFromCoreData.map({ dataArray(song: $0) })
    }

func numberOfSections(in tableView: UITableView) -> Int {
        return 2
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        switch section {
        case 0:
            return data.count
        case 1:
            return isLoadingMore ? 1 : 0
        default:
            return 0
        }
    }

func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) {
        if ((scrollView.contentOffset.y + scrollView.frame.size.height) >= scrollView.contentSize.height){
            loadData()
        }
    }

func setupForCeckingAvailableData() {
        utility.checkInternetAccess = { [weak self] result in
            if result {
                self?.paging = Paging()
                self?.loadData()
            } else {
                self?.loadDataFromCoreData()
            }
        }
    }
override func viewDidLoad() {
        super.viewDidLoad()

        setupForCeckingAvailableData()

    }

so some time when I first time load or try fetch new data by scrolling to the end of table I got a crash with the message is因此,当我第一次加载或尝试通过滚动到表末尾来获取新数据时,我遇到了崩溃的消息是

Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (0) must be equal to the number of rows contained in that section before the update (10), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).

So what the cause of it?那么它的原因是什么呢? Why got that crash even though I already use reloadData() every time I append a new data to variable data .为什么即使我已经使用reloadData()每次我 append a new data to variable data都会发生崩溃。 Should I change reloadData() to我应该将reloadData()更改为

tableView.beginUpdates()
tableView.insertRows(at: indexPaths, with: .automatic)
tableView.endUpdates()

? ? if that so, is that the crash cause insertRows only refresh specific row and section so no take a loot of time to refresh table with a loot of datas??如果是这样,那是崩溃导致insertRows只刷新特定的行和部分,所以不需要花费大量时间来刷新带有大量数据的表吗? That's all of my question, Thank you这就是我的全部问题,谢谢

I just want to point out something else.我只是想指出点别的。 Generally speaking, Singletons are Evil and I avoid them like the plague.一般来说,单身人士是邪恶的,我像避免瘟疫一样避免他们。

This is a real big code smell and would advise you to stop using this type of code:这是一个真正的大代码气味,建议您停止使用这种类型的代码:

TableView.beginUpdates()
TableView.insertRows(at: indexPaths, with: .automatic)
TableView.endUpdates()

See What is so bad about singletons?看看单例有什么不好? there are many more blog posts about it.还有更多关于它的博客文章。

after I do some research I found a clue.在我做了一些研究后,我发现了一个线索。 I add tableView.reloadData() before tableView.reloadSections(IndexSet(integer: 1), with: .automatic) because when I see the crashlytic crash happend at tableView.reloadSections(IndexSet(integer: 1), with: .automatic)我在tableView.reloadSections(IndexSet(integer: 1), with: .automatic) ) 之前添加tableView.reloadData() ) 因为当我看到在tableView.reloadSections(IndexSet(integer: 1), with: .automatic) .automatic) 发生崩溃时

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 无效的更新:iOS中第0部分的无效行数 - Invalid update: invalid number of rows in section 0 in iOS iOS 5:更新无效:部分中的行数无效 - ios 5: Invalid update: invalid number of rows in section 无效更新:第0部分UITableView中的行数无效 - Invalid update: invalid number of rows in section 0 UITableView NSInternalInconsistencyException(无效更新:第0部分无效的行数) - NSInternalInconsistencyException(Invalid update: invalid number of rows in section 0) 无效的更新:部分中的行数无效 - Invalid update: invalid number of rows in section '无效更新:第 0 节中的行数无效 - 'Invalid update: invalid number of rows in section 0 无效的更新:部分中的行数无效 - Invalid update: invalid number of rows in section 无效更新:使用 NSFetchedResultsController 的第 0 节中的行数无效 - Invalid update: invalid number of rows in section 0 with NSFetchedResultsController iOS 8:从NSFetchedResultsController的委托捕获了一个异常,无效的更新:第0节中的行数无效 - iOS 8: An exception was caught from the delegate of NSFetchedResultsController, Invalid update: invalid number of rows in section 0 NSInternalInconsistencyExceptionException原因:'无效的更新:部分0中的行数无效' - NSInternalInconsistencyException reason: 'Invalid update: invalid number of rows in section 0'
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM