UITableView的数据源未更新数组

时间:2018-12-13 18:41:20

标签: ios swift uitableview

我正在为UITableView创建一个数据源。数据源负责使用WeatherViewModel类显示天气信息。这是WeatherDataSource的实现。

class WeatherDataSource: NSObject, UITableViewDataSource {

    var cellIdentifier: String
    var weatherViewModels = [WeatherViewModel]()

    init(cellIdentifier: String, weatherViewModels: [WeatherViewModel]) {
        self.cellIdentifier = cellIdentifier
        self.weatherViewModels = weatherViewModels
    }

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

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print(self.weatherViewModels.count) // This is always empty
        return self.weatherViewModels.count
    }
// some other methods

在View Controller中,如下所示初始化数据源:

 override func viewDidLoad() {

        super.viewDidLoad()
        self.navigationController?.navigationBar.prefersLargeTitles = true

        self.datasource = WeatherDataSource(cellIdentifier: "WeatherCell", weatherViewModels: self.weatherListViewModel.weatherViewModels)

        self.tableView.dataSource = self.datasource
    }

添加新项目时,将其添加到WeatherListViewModel视图模型的weatherViewModels集合中,如下所示:

 func addWeatherDidSave(vm: WeatherViewModel) {

        self.weatherListViewModel.addWeatherViewModel(vm)
        print(self.weatherListViewModel.weatherViewModels.count) // this prints 1
        self.tableView.reloadData()
    }

上面的self.weatherListViewModel.weatherViewModels.count表示1,表示已插入项目。但是当我重新加载tableview时,WeatherDataSource weatherViewModels内部仍然是空的!这是为什么?创建WeatherDataSource时,我将相同的数组传递给它。现在,我正在修改数组,这样它就不会自动反映在数据源中。

更新:ViewModel代码

class WeatherListViewModel {

    private(set) var weatherViewModels = [WeatherViewModel]()

     func addWeatherViewModel(_ vm: WeatherViewModel) {
        self.weatherViewModels.append(vm)
    }

class WeatherViewModel: Decodable {

    let name: String
    var currentTemperature: TemperatureViewModel

    private enum CodingKeys: String, CodingKey {
        case name
        case currentTemperature = "main"
    }

}

解决方案:我的解决方案是向数据源添加一个更新方法,并传递更新后的数组。我不是很喜欢它,但是可以。

  func update(weatherViewModels: [WeatherViewModel]) {
        self.weatherViewModels = weatherViewModels
    }

然后在View Controller中可以像这样使用它:

func addWeatherDidSave(vm:WeatherViewModel){

 self.weatherListViewModel.addWeatherViewModel(vm)
    self.datasource?.update(weatherViewModels: self.weatherListViewModel.weatherViewModels)
    self.tableView.reloadData()
}

3 个答案:

答案 0 :(得分:1)

您的问题是您将self.weatherListViewModel.weatherViewModels而不是self.weatherListViewModel传递给WeatherDataSource实例。

由于self.weatherListViewModel.weatherViewModels是一个数组,因此它是一个值类型,而不是引用类型。

这意味着weatherViewModels实例中的WeatherDataSourceweatherViewModels实例中的WeatherListViewModel不同的数组。尽管WeatherDataSource是类,因此是引用类型,但属性本身是值类型。您需要始终对WeatherListViewModel实例中的数组进行操作。

class WeatherDataSource: NSObject, UITableViewDataSource {

    var cellIdentifier: String
    var weatherViewModel: WeatherListViewModel

    init(cellIdentifier: String, weatherViewModel: WeatherListViewModel) {
        self.cellIdentifier = cellIdentifier
        self.weatherViewModel = weatherViewModel
    }

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

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print(self.weatherViewModel.weatherViewModels.count) 
        return self.weatherViewModel.weatherViewModels.count
    }
}

ViewController

override func viewDidLoad() {

    super.viewDidLoad()
    self.navigationController?.navigationBar.prefersLargeTitles = true

    self.datasource = WeatherDataSource(cellIdentifier: "WeatherCell", weatherViewModels: self.weatherListViewModel)

    self.tableView.dataSource = self.datasource
}

答案 1 :(得分:0)

您没有显示self.weatherListViewModel.addWeatherViewModel()的代码,但是如果该方法仅更新self.weatherListViewModel数组,则此更改不会传播到您的WeatherDataSource实例,因为它正在运行您在初始化时传递的所有内容的副本。

答案 2 :(得分:0)

要更改行数,您需要通过添加/删除对象或为其分配新数组来更改 self.datasource.weatherViewModels 数组。您的代码无法做到这一点。