我想在一个单独的类中实现dataSource。 我的实现似乎在这里工作
这是我的 UITableViewController
class MasterViewController: UITableViewController {
@IBOutlet weak var itemsTableView: UITableView!
let loginManager = LoginManager.shared
let preferences = UserDefaultsManager.shared
let appDelegate = UIApplication.shared.delegate
var delegate: PreferencesDelegate?
let apiClient = ApiClient.shared
var timer:Timer?
var count: Int = 10
var items:[Item]? {
didSet {
let dataSource = ItemDataSource(items: items!)
tableView.dataSource = dataSource
tableView.reloadData()
//itemsTableView.dataSource = self
//itemsTableView.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
configureView()
}
func configureView() {
self.navigationController?.navigationBar.topItem?.title = "You are logged in"
apiClient.getData { (items) in
DispatchQueue.main.async {
self.items = items
self.tableView.reloadData()
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
//seconds delay before starting timer
self.runTimer()
}
}
func runTimer() {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(MasterViewController.updateTimer)), userInfo: nil, repeats: true)
}
@objc func updateTimer() {
if count > 0 {
count -= 1
self.navigationController?.navigationBar.topItem?.title = "session will expire in \(count) seconds"
}
if count == 0 {
preferences.clear()
pushToLoginVC()
timer?.invalidate()
}
}
func pushToLoginVC() {
let navigationCoordinator = NavigationCoordinator(window: appDelegate!.window!!)
navigationCoordinator.setRoot(id: "LoginVC")
delegate?.getCurrentUser()
}
}
这是 DataSource 类
class ItemDataSource: NSObject, UITableViewDataSource {
private var items: [Item]
init(items: [Item]) {
self.items = items
super.init()
}
// MARK: - Data Source
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
print("configure cell triggered")
let itemCell = tableView.dequeueReusableCell(withIdentifier: "itemCell", for: indexPath) as! ItemViewCell
let item = items[indexPath.row]
let cellViewModel = ItemViewModel(item: item)
itemCell.configure(viewModel: cellViewModel)
return itemCell
}
// MARK: - Helper
func item(at indexPath: IndexPath) -> Item {
return items[indexPath.row]
}
}
小区标识符设置为“itemCell” 自定义类也设置为“ItemViewCell”
分配数据源。我用这些项初始化数据源 我放了断点,我注意到** cellForRowAt indexPath 永远不会被调用。**
从json文件中读取数据。数组不为空。它经过测试。 tableView.dataSource不是nil。该应用程序不会崩溃 主要问题是cellForRowAt indexPath。我似乎无法想象。我可以将所有数据源方法保存在同一个MasterViewController中,尽管我真的希望保持数据源方法以获得更好的代码质量,主要是当viewcontroller变大时
有人在想吗?
答案 0 :(得分:0)
更新我的问题:
根据我收到的答案,我添加了 var dataSource:ItemDataSource 作为强参考。
如果dataSource是本地的,则dataSource很弱并且不会被保留
类MasterViewController:UITableViewController {
@IBOutlet weak var itemsTableView: UITableView!
let loginManager = LoginManager.shared
let preferences = UserDefaultsManager.shared
let appDelegate = UIApplication.shared.delegate
var delegate: PreferencesDelegate?
let apiClient = ApiClient.shared
var timer:Timer?
var count: Int = 10
**var dataSource:ItemDataSource?**
var items:[Item]? {
didSet {
**dataSource = ItemDataSource(items: items!)**
tableView.dataSource = dataSource
tableView.reloadData()
}
}
override func viewDidLoad() {
super.viewDidLoad()
configureView()
}
func configureView() {
self.navigationController?.navigationBar.topItem?.title = "You are logged in"
apiClient.getData { (items) in
DispatchQueue.main.async {
self.items = items
}
}
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
//seconds delay before starting timer
self.runTimer()
}
}
func runTimer() {
timer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(MasterViewController.updateTimer)), userInfo: nil, repeats: true)
}
@objc func updateTimer() {
if count > 0 {
count -= 1
self.navigationController?.navigationBar.topItem?.title = "session will expire in \(count) seconds"
}
if count == 0 {
preferences.clear()
pushToLoginVC()
timer?.invalidate()
}
}
func pushToLoginVC() {
let navigationCoordinator = NavigationCoordinator(window: appDelegate!.window!!)
navigationCoordinator.setRoot(id: "LoginVC")
delegate?.getCurrentUser()
}
}