Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
iOS:无效更新:节0中的行数无效_Ios_Swift_Uitableview - Fatal编程技术网

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

iOS:无效更新:节0中的行数无效,ios,swift,uitableview,Ios,Swift,Uitableview,我创建了一个表视图,每当我滚动到表的末尾时,它都会在表的第1部分显示shimmer,以等待api加载新数据。api完成加载数据后,新数据将附加到用于包含显示到节0上的表视图的所有数据的数组中,然后重新加载表视图以将节1 numberOfRowsInSection更新为0以隐藏垫片并更新节0 numberOfRowsInSection 这就是我的代码示例 fileprivate var data = [dataArray]() { didSet { guar

我创建了一个表视图,每当我滚动到表的末尾时,它都会在表的第1部分显示shimmer,以等待api加载新数据。api完成加载数据后,新数据将附加到用于包含显示到节0上的表视图的所有数据的数组中,然后重新加载表视图以将节1 numberOfRowsInSection更新为0以隐藏垫片并更新节0 numberOfRowsInSection

这就是我的代码示例

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

    }

所以,当我第一次加载或试图通过滚动到表的末尾来获取新数据时,我遇到了一个崩溃,消息是

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).
那么原因是什么呢?为什么每次我向变量
data
添加新数据时,我都会使用
reloadData()。我应该将
reloadData()
更改为

tableView.beginUpdates()
tableView.insertRows(at: indexPaths, with: .automatic)
tableView.endUpdates()
??如果是这样的话,是不是崩溃原因导致
insertRows
只刷新特定的行和节,所以不需要花费大量的时间来用大量的数据刷新表??
这就是我所有的问题,谢谢你。我只想指出一些其他的问题。 一般来说,单身汉是邪恶的,我像躲避瘟疫一样躲避他们

这是一个很大的代码气味,建议您停止使用这种类型的代码:

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

看,还有更多关于它的博客帖子。

在我做了一些研究之后,我发现了一个线索。
我将
tableView.reloadData()
添加到
tableView.reloadSections(IndexSet(integer:1),带:.automatic)
之前,因为当我看到崩溃发生在
tableView.reloadSections(IndexSet(integer:1),带:.automatic)

时,我发布的评论来自这个问题,所以这个问题已经被编辑以删除单例用法。是的,那么我的-1需要被设置回0。@David Thorn没问题,明白了,它从来都不是单例。OP只是有一个坏习惯,变量名以大写字母开头。答案永远不适用。