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 == ... {} 会更清楚。您冒着代码逐渐变得无法摆脱的风险。我已经去过那里了 ;)