在MVVM中清除集合视图的正确方法

时间:2018-05-11 21:33:27

标签: swift mvvm uicollectionview

我有一个由视图模型驱动的集合视图。当用户注销时,我想清除视图模型和集合视图。但是,只要我在清除视图模型时尝试调用collectionView?.reload(),程序就会崩溃:request for number of items in section 6 when there are only 0 sections in the collection view

class ViewModel {

    private var childVMs: [ChildViewModel]()

    var numberOfSections { return childVMs.count }

    func numberOfItems(inSection section: Int) {
        return childVMs[section].numberOfItems
    }

    func clear() {
        childVMs.removeAll()
    }
    ...
}

class ViewController: UICollectionViewController {

    let vm = ViewModel()

    func logout() {
        vm.clear()
        collectionView?.reloadData()
    }

    override func numberOfSections(in collectionView: UICollectionView) -> Int {
        return vm.numberOfSections
    }

    override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return vm.numberOfItems(inSection: section)
    }

    ...
}

我注意到程序崩溃时,numberOfSections(in)按预期返回0,甚至没有调用collectionView(_, numberOfItemsInSection)。关于哪里可能出错的任何想法?

2 个答案:

答案 0 :(得分:0)

因为您已经删除了所有ChildViewModel,所以在调用函数numberOfItems(inSection section:Int)之前,childVMs是空数组。它使你的应用程序崩溃,因为你在空数组中得到一个元素:childVMs [section],childVMs.count对于空数组是安全的。

答案 1 :(得分:0)

我解决了。事实证明问题出在我的自定义UICollectionViewFlowLayout中。在其中,我调用了let numberOfItems = collectionView?.numberOfItems(inSection: section),其中section由我的数据源决定。所以我之前添加了一份警卫声明,一切都很美妙:

guard let numberOfSections = collectionView?.numberOfSections,
            numberOfSections > section else { return }

你们都无法想到这一点,我完全没想到问题出在哪里。所以我想在这里发布这个问题,以便将来可能遇到与reloadData()类似问题的人----记得查看自定义布局!