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



我有一个由视图模型驱动的集合视图。当用户注销时,我想清除视图模型和集合视图。但是每当我尝试调用视图模型时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)。关于哪里出了问题的任何想法?

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

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

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

你们不可能都弄清楚这一点,我完全没想到这就是问题所在。所以我只想在这里发布这个,供将来可能遇到类似reloadData()问题的人使用----记得检查您的自定义布局!

最新更新