TableView 索引超出范围问题
TableView Index out of range issue
我的视图控制器打开一个目录,计算其中的文件类型并将结果存储在文件类型和计数的字典 [String:Int] 中。我有一个显示这个的 TableView。
我第一次打开目录时,ViewController 正确显示了 FileTypeTableview 中的信息。如果我尝试打开另一个目录,执行到行:
let dialogButton = dialog.runModal()
然后立即跳转到我的 TableView 函数中的一行,并在此处抛出一个超出范围的索引:
val = types[row]
Types 是一个 [String] 并显示 0 个元素,row 是一个 Int 并显示 0。
我对 dialog.runModal() 函数调用时发生的事实感到困惑。
下面是获取目录和显示 TableViews 的函数。
我是 Swift 和 MacOS 编程的新手,非常感谢任何见解。
@IBAction func getFolder(_ sender: Any) {
let dialog = NSOpenPanel()
dialog.canChooseDirectories = true
dialog.canChooseFiles = false
allFiles = []
fileTypesDict.removeAll()
let dialogButton = dialog.runModal()
if let theURL = dialog.url {
theDirectory = theURL.path
allFilesAsPaths = getAllFiles2(atDirectoryPath: theURL.path)
allFilesAsPaths.sort()
}
fileCountLabel.stringValue = String(allFilesAsPaths.count)
mainTableView2.reloadData()
fileTypeTableView.reloadData()
}
func numberOfRows(in tableView: NSTableView) -> Int {
var numberOfRows : Int = 0
if tableView == mainTableView2 {
print("number of rows for mainTableView2")
numberOfRows = allFilesAsPaths.count
} else if tableView == fileTypeTableView {
print("number of rows for fileTypeTableView")
numberOfRows = fileTypesDict.count
} else if tableView == exifTableView {
numberOfRows = exifData.count
print("exifData.count = \(exifData.count)")
print("number of rows for exifTableview \(numberOfRows)")
}
return numberOfRows
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
var val : String = ""
if tableView == mainTableView2 {
val = allFilesAsPaths[row]
}
if tableView == exifTableView {
if tableColumn?.identifier.rawValue == "tag" {
let tagArray : [String] = Array(exifData.keys)
val = tagArray[row]
} else if tableColumn?.identifier.rawValue == "value" {
let valueArray : [String] = Array(exifData.values)
val = valueArray[row]
}
}
if tableView == fileTypeTableView {
let types : [String] = Array(fileTypesDict.keys)
let counts : [Int] = Array(fileTypesDict.values)
if tableColumn?.identifier.rawValue == "type" {
val = types[row]
} else {
val = String(counts[row])
}
}
return val
}
我认为你应该尝试删除
allFiles = []
fileTypesDict.removeAll()
并在对话框验证后立即设置所有数组。因为看起来显示对话框会触发 table 的更新,但此时,您的对象不同步,因为您之前和之后都做了一些工作。
顺便说一句,如果你分开 table 类 比处理 if tableView == ... {}
会更清楚。您冒着代码逐渐变得无法摆脱的风险。我已经去过那里了 ;)
我的视图控制器打开一个目录,计算其中的文件类型并将结果存储在文件类型和计数的字典 [String:Int] 中。我有一个显示这个的 TableView。
我第一次打开目录时,ViewController 正确显示了 FileTypeTableview 中的信息。如果我尝试打开另一个目录,执行到行:
let dialogButton = dialog.runModal()
然后立即跳转到我的 TableView 函数中的一行,并在此处抛出一个超出范围的索引:
val = types[row]
Types 是一个 [String] 并显示 0 个元素,row 是一个 Int 并显示 0。 我对 dialog.runModal() 函数调用时发生的事实感到困惑。
下面是获取目录和显示 TableViews 的函数。 我是 Swift 和 MacOS 编程的新手,非常感谢任何见解。
@IBAction func getFolder(_ sender: Any) {
let dialog = NSOpenPanel()
dialog.canChooseDirectories = true
dialog.canChooseFiles = false
allFiles = []
fileTypesDict.removeAll()
let dialogButton = dialog.runModal()
if let theURL = dialog.url {
theDirectory = theURL.path
allFilesAsPaths = getAllFiles2(atDirectoryPath: theURL.path)
allFilesAsPaths.sort()
}
fileCountLabel.stringValue = String(allFilesAsPaths.count)
mainTableView2.reloadData()
fileTypeTableView.reloadData()
}
func numberOfRows(in tableView: NSTableView) -> Int {
var numberOfRows : Int = 0
if tableView == mainTableView2 {
print("number of rows for mainTableView2")
numberOfRows = allFilesAsPaths.count
} else if tableView == fileTypeTableView {
print("number of rows for fileTypeTableView")
numberOfRows = fileTypesDict.count
} else if tableView == exifTableView {
numberOfRows = exifData.count
print("exifData.count = \(exifData.count)")
print("number of rows for exifTableview \(numberOfRows)")
}
return numberOfRows
}
func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {
var val : String = ""
if tableView == mainTableView2 {
val = allFilesAsPaths[row]
}
if tableView == exifTableView {
if tableColumn?.identifier.rawValue == "tag" {
let tagArray : [String] = Array(exifData.keys)
val = tagArray[row]
} else if tableColumn?.identifier.rawValue == "value" {
let valueArray : [String] = Array(exifData.values)
val = valueArray[row]
}
}
if tableView == fileTypeTableView {
let types : [String] = Array(fileTypesDict.keys)
let counts : [Int] = Array(fileTypesDict.values)
if tableColumn?.identifier.rawValue == "type" {
val = types[row]
} else {
val = String(counts[row])
}
}
return val
}
我认为你应该尝试删除
allFiles = []
fileTypesDict.removeAll()
并在对话框验证后立即设置所有数组。因为看起来显示对话框会触发 table 的更新,但此时,您的对象不同步,因为您之前和之后都做了一些工作。
顺便说一句,如果你分开 table 类 比处理 if tableView == ... {}
会更清楚。您冒着代码逐渐变得无法摆脱的风险。我已经去过那里了 ;)