致命错误:追加数组时数组索引超出范围
Posted
技术标签:
【中文标题】致命错误:追加数组时数组索引超出范围【英文标题】:Fatal error: Array index out of range when appending array 【发布时间】:2019-05-28 21:08:22 【问题描述】:我目前有一个要附加选项的数组。它们显示在一个包含 3 个部分的表格中。前 2 部分各有 1 行,但第三部分的行数可变,具体取决于附加到数组的内容。我基本上采用了初始数组的第三个组件(allAlbums[0].markscheme)并将其分解以在数组中创建多个新项目。
但是,当我尝试对此进行模拟时,我在 'cell.textData?.text = section[indexPath.row] as! 上得到了一个致命数组! String',我不知道为什么?
final class CaseViewController: UIViewController, UITableViewDelegate, UITableViewDataSource
@IBOutlet var titleText: UILabel!
@IBOutlet var tableView: UITableView!
private var allAlbums = [Case]()
let kHeaderSectionTag: Int = 6900;
var expandedSectionHeaderNumber: Int = -1
var expandedSectionHeader: UITableViewHeaderFooterView!
var sectionItems: Array<Any> = []
var sectionNames: Array<Any> = []
var markschemeRows: Array<Any> = []
override func viewDidLoad()
super.viewDidLoad()
allAlbums = LibraryAPI.shared.getCases()
// Filter the main array to match a single case
allAlbums = allAlbums.filter $0.title == title
// Get data to fill in to table
sectionNames = [ "Trainee Information", "Patient Information", "Examiner Information" ];
sectionItems = [ [allAlbums[0].doctor], [allAlbums[0].patient], [allAlbums[0].markscheme]]
let text = allAlbums[0].markscheme
markschemeRows = text.components(separatedBy: " ")
sectionItems.append(contentsOf: markschemeRows)
// Autoresize rows
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 500
// Remove excess row seperators
tableView.tableFooterView = UIView()
tableView.separatorColor = UIColor.clear
titleText.text = title
func numberOfSections(in tableView: UITableView) -> Int
return 3
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int
if (self.expandedSectionHeaderNumber == section)
// Header section
let header = self.sectionNames[section] as! String
// If markscheme, create the markscheme format
if (header == "Examiner Information")
print(self.markschemeRows.count)
return self.markschemeRows.count
else
let arrayOfItems = self.sectionItems[section] as! NSArray
print(arrayOfItems.count)
return arrayOfItems.count
else
return 0;
func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String?
if (self.sectionNames.count != 0)
return self.sectionNames[section] as? String
return ""
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat
return 44.0;
func tableView(_ tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat
return 0;
func tableView(_ tableView: UITableView, willDisplayHeaderView view: UIView, forSection section: Int)
//recast your view as a UITableViewHeaderFooterView
let header: UITableViewHeaderFooterView = view as! UITableViewHeaderFooterView
header.contentView.backgroundColor = UIColor.darkGray
header.textLabel?.textColor = UIColor.white
if let viewWithTag = self.view.viewWithTag(kHeaderSectionTag + section)
viewWithTag.removeFromSuperview()
let headerFrame = self.view.frame.size
let theImageView = UIImageView(frame: CGRect(x: headerFrame.width - 32, y: 13, width: 18, height: 18));
theImageView.image = UIImage(named: "Chevron-Dn-Wht")
theImageView.tag = kHeaderSectionTag + section
header.addSubview(theImageView)
// make headers touchable
header.tag = section
let headerTapGesture = UITapGestureRecognizer()
headerTapGesture.addTarget(self, action: #selector(CaseViewController.sectionHeaderWasTouched(_:)))
header.addGestureRecognizer(headerTapGesture)
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! CustomTableCell
let section = self.sectionItems[indexPath.section] as! NSArray
cell.textLabel?.textColor = UIColor.black
cell.textData?.text = section[indexPath.row] as! String
return cell
func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath)
tableView.deselectRow(at: indexPath, animated: true)
// MARK: - Expand / Collapse Methods
@objc func sectionHeaderWasTouched(_ sender: UITapGestureRecognizer)
let headerView = sender.view as! UITableViewHeaderFooterView
let section = headerView.tag
let eImageView = headerView.viewWithTag(kHeaderSectionTag + section) as? UIImageView
if (self.expandedSectionHeaderNumber == -1)
self.expandedSectionHeaderNumber = section
tableViewExpandSection(section, imageView: eImageView!)
else
if (self.expandedSectionHeaderNumber == section)
tableViewCollapeSection(section, imageView: eImageView!)
else
let cImageView = self.view.viewWithTag(kHeaderSectionTag + self.expandedSectionHeaderNumber) as? UIImageView
tableViewCollapeSection(self.expandedSectionHeaderNumber, imageView: cImageView!)
tableViewExpandSection(section, imageView: eImageView!)
func tableViewCollapeSection(_ section: Int, imageView: UIImageView)
let sectionData = self.sectionItems[section] as! NSArray
self.expandedSectionHeaderNumber = -1;
if (sectionData.count == 0)
return;
else
UIView.animate(withDuration: 0.4, animations:
imageView.transform = CGAffineTransform(rotationAngle: (0.0 * CGFloat(Double.pi)) / 180.0)
)
var indexesPath = [IndexPath]()
for i in 0 ..< sectionData.count
let index = IndexPath(row: i, section: section)
indexesPath.append(index)
self.tableView!.beginUpdates()
self.tableView!.deleteRows(at: indexesPath, with: UITableView.RowAnimation.fade)
self.tableView!.endUpdates()
func tableViewExpandSection(_ section: Int, imageView: UIImageView)
let sectionData = self.sectionItems[section] as! NSArray
if (sectionData.count == 0)
self.expandedSectionHeaderNumber = -1;
return;
else
UIView.animate(withDuration: 0.4, animations:
imageView.transform = CGAffineTransform(rotationAngle: (180.0 * CGFloat(Double.pi)) / 180.0)
)
var indexesPath = [IndexPath]()
// Header section
let header = self.sectionNames[section] as! String
// If markscheme, create the markscheme format
if (header == "Examiner Information")
for i in 0 ..< markschemeRows.count
let index = IndexPath(row: i, section: section)
indexesPath.append(index)
else
for i in 0 ..< sectionData.count
let index = IndexPath(row: i, section: section)
indexesPath.append(index)
self.expandedSectionHeaderNumber = section
self.tableView!.beginUpdates()
self.tableView!.insertRows(at: indexesPath, with: UITableView.RowAnimation.fade)
self.tableView!.endUpdates()
【问题讨论】:
【参考方案1】:错误很明显。
在 numberOfRows
中,您为第 2 部分返回 markschemeRows.count
,这是该行中分隔项目的数量
markschemeRows = text.components(separatedBy: " ")
那么你还必须从markschemeRows
而不是section[indexPath.row]
中的cellForRow
获取项目
var markschemeRows = [String]()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "tableCell", for: indexPath) as! CustomTableCell
let section = self.sectionItems[indexPath.section] as! NSArray
cell.textLabel?.textColor = UIColor.black
if indexPath.section == 2
cell.textData?.text = markschemeRows[indexPath.row]
else
cell.textData?.text = section[indexPath.row] as! String
return cell
您的代码相当繁琐。例如sectionNames
和markschemeRows
显然是[String]
。为什么将数组声明为[Any]
?这是斯威夫特。 注意类型。并且根本不要在 Swift 中使用像 NSArray
这样的 Foundation 集合类型。再次注意类型。
【讨论】:
太棒了!谢谢!抱歉,我只是在学习,所以我正在整理代码 - 感谢您指出这一点:)以上是关于致命错误:追加数组时数组索引超出范围的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI - 致命错误:从数组中删除元素时索引超出范围
致命错误:在Swift中访问10个元素的数组时,数组索引超出范围