代码之家  ›  专栏  ›  技术社区  ›  Jack Guo

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

  •  0
  • Jack Guo  · 技术社区  · 6 年前

    我有一个由视图模型驱动的集合视图。当用户注销时,我想清除视图模型和集合视图。但每次我打电话都会导致程序崩溃 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 回复  |  直到 6 年前
        1
  •  0
  •   tphduy    6 年前

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

        2
  •  0
  •   Jack Guo    6 年前

    我解决了它。原来问题出在我的习惯上 UICollectionViewFlowLayout .在里面,我打过电话 let numberOfItems = collectionView?.numberOfItems(inSection: section) 哪里 section 由我的数据源确定。所以我在之前添加了一份守卫声明,一切都很顺利:

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

    你们不可能都明白这一点,我完全没想到这就是问题所在。所以我只想把这个贴在这里,给那些可能遇到类似问题的人 reloadData() 将来----记得检查你的自定义布局!