嵌套UITableView滚动时数组越界崩溃问题求助
嵌套UITableView数据量大时崩溃的解决方案
核心崩溃原因:数组越界
你的内部UITableView的numberOfRowsInSection方法逻辑完全错误:
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return memberTestPackageArray.count // 错误! }
memberTestPackageArray是对应每个section的行数据数组([[String]]类型),每个section的行数应该是该section对应的子数组长度,也就是memberTestPackageArray[section].count。当前代码返回的是总section数,当某个section的行索引超过memberTestPackageArray.count时,直接触发数组越界崩溃,数据量越大越容易触发。
其他潜在问题修复
1. 主TableView的section数量计算错误
主VC的numberOfSections方法里,sectionArray是普通二维数组,不存在results属性,应直接返回数组长度:
func numberOfSections(in tableView: UITableView) -> Int { return sectionArray.count }
2. 内部TableView的高度与刷新逻辑
嵌套TableView需要确保内部表能正确计算高度,且数据更新后及时刷新:
- 在
RevampTableViewCell的awakeFromNib中配置内部表:
override func awakeFromNib() { super.awakeFromNib() bookingViewMembersTableview.delegate = self bookingViewMembersTableview.dataSource = self bookingViewMembersTableview.rowHeight = UITableView.automaticDimension bookingViewMembersTableview.estimatedRowHeight = 44 // 设置合理的预估高度 }
- 给
RevampTableViewCell的数组添加属性观察器,数据更新后自动刷新内部表:
var sectionArray = [String]() { didSet { bookingViewMembersTableview.reloadData() } } var memberTestPackageArray = [[String]]() { didSet { bookingViewMembersTableview.reloadData() } }
3. 避免复用导致的旧数据残留
在RevampTableViewCell的prepareForReuse方法中重置数据,防止复用旧cell时显示错误内容:
override func prepareForReuse() { super.prepareForReuse() sectionArray.removeAll() memberTestPackageArray.removeAll() bookingViewMembersTableview.reloadData() }
修复后的内部TableView数据源方法(带安全判断)
func numberOfSections(in tableView: UITableView) -> Int { return sectionArray.count } func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // 安全判断:防止section索引越界 guard section < memberTestPackageArray.count else { return 0 } return memberTestPackageArray[section].count } func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let bookingViewMemberCell = tableView.dequeueReusableCell(withIdentifier: "BookingViewMembersTableViewCell", for: indexPath) as! BookingViewMembersTableViewCell // 双重安全判断,彻底避免数组越界崩溃 guard indexPath.section < memberTestPackageArray.count, indexPath.row < memberTestPackageArray[indexPath.section].count else { bookingViewMemberCell.testPackageNameLabel.text = "" return bookingViewMemberCell } bookingViewMemberCell.testPackageNameLabel.text = memberTestPackageArray[indexPath.section][indexPath.row] return bookingViewMemberCell }
内容的提问来源于stack exchange,提问作者Abhishek kumar
相关产品推荐
相关产品推荐

