我注意到,当我手动设置tableview数据源时,必须保留对其的强烈引用,否则,将不会调用cellForRowAt
。 (请注意,numberOfRowsInSection
和numberOfSections
被调用了
class YAExploreViewController: UIViewController {
...
dataSourceSubject
.subscribe(onNext: { dataSource in
// I'm not storing a strong reference to the dataSource, and cellForRowAt wouldn't get called
self.tableView.dataSource = dataSource
self.tableView.reloadData()
})
.disposed(by: self.bag)
...
}
解决方案:
class YAExploreViewController: UIViewController {
var exploreDataSource: YAExploreDataSource?
...
dataSourceSubject
.subscribe(onNext: { dataSource in
// I'm storing a strong reference to the dataSource, and cellForRowAt got called
self.dataSource = dataSource
self.tableView.dataSource = self.dataSource
self.tableView.reloadData()
})
.disposed(by: self.bag)
...
}
我注意到tableView dataSource属性上有一个描述:
用作表视图的数据源的对象。数据 源必须采用UITableViewDataSource协议。数据来源 没有保留。
我想知道这是否相关。
谢谢
答案 0 :(得分:0)
在表格视图中,dataSource
属性遵循“委托模式”(在UIKit中广泛使用),这意味着它必须为weak
,并且必须自己保留。
主要原因是,如果表视图强烈引用dataSource
,则在许多情况下(例如,如果您的视图控制器是数据源)它可能会创建一个引用周期和内存泄漏。
class MyController: UIViewController {
@IBOutlet var tableview: UITableView?
override func viewDidLoad() {
super.viewDidLoad()
tableview?.dataSource = self
}
}
extension MyController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 0
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
return UITableViewCell(frame: .zero)
}
}
如果dataSource
是strong
引用,则将导致内存泄漏。
如果您想进一步了解Swift中的内存管理方式,请查看Automatic Reference Counting文档。