我认为惰性 var {}() 应该运行一次。但今天我遇到这个问题让我很困扰。我有任何想法。我哭了。
这是再现类:
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
private lazy var hotStockTableView: UITableView = {
let tableView = UITableView()
print("hotStockTableView ======> \(tableView) \n")
tableView.delegate = self
tableView.dataSource = self
// Here cause crash.
tableView.tableFooterView = UIView() // if comment this line, everthing is ok.
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
return tableView
}()
override func viewDidLoad() {
super.viewDidLoad()
view.addSubview(hotStockTableView)
hotStockTableView.frame = view.bounds
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("tableView =====> \(tableView) \n")
if tableView == hotStockTableView {
return 5
} else {
return 0
}
}
func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
var cell = tableView.dequeueReusableCell(withIdentifier: "cell")
if cell == nil {
cell = UITableViewCell(style: .default, reuseIdentifier: "cell")
}
cell?.textLabel?.text = "\(indexPath.row)"
return cell!
}
}
Run Code Online (Sandbox Code Playgroud)
有人可以帮助我吗?
问题是创建表视图的闭包最终是递归的。
当您在桌子上设置 tableFooterView 时,它会立即尝试找出该页脚是否应该立即绘制/可见/在屏幕上。
要知道页脚是否可见,表视图必须找出当前应显示多少行,因此它会向数据源(您的视图控制器)询问第一部分中的行数
在你的方法中tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
,你有这条线if tableView == hotStockTableView {
。这尝试访问惰性hotStockTableView
变量,它仍然没有完成初始化,因为该闭包是首先调用此代码的
因此,惰性 var 闭包再次启动,并一遍又一遍地递归执行相同的步骤,直到堆栈溢出并崩溃。
幸运的是,解决方案很简单。如果您尚未设置数据源,则添加表视图页脚将永远不会调用您的行数数据源方法。因此,只需将惰性闭包中的代码顺序更改为以下内容:
private lazy var hotStockTableView: UITableView = {
let tableView = UITableView()
print("hotStockTableView ======> \(tableView) \n")
tableView.tableFooterView = UIView()
tableView.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
tableView.delegate = self
tableView.dataSource = self
return tableView
}()
Run Code Online (Sandbox Code Playgroud)
现在你的代码就可以正常工作了。
归档时间: |
|
查看次数: |
1670 次 |
最近记录: |