我正在为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()
}
答案 0 :(得分:1)
您的问题是您将self.weatherListViewModel.weatherViewModels
而不是self.weatherListViewModel
传递给WeatherDataSource
实例。
由于self.weatherListViewModel.weatherViewModels
是一个数组,因此它是一个值类型,而不是引用类型。
这意味着weatherViewModels
实例中的WeatherDataSource
和weatherViewModels
实例中的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 数组。您的代码无法做到这一点。