一尘不染

如何在Swift中捕获“索引超出范围”?

swift

我真的很想在我的Swift代码中使用一个更简单的经典try catch块,但是我找不到能做到这一点的任何东西。

我只需要:

try {
// some code that causes a crash.
}
catch {
// okay well that crashed, so lets ignore this block and move on.
}

这是我的难题,当TableView重新加载新数据时,某些信息仍位于RAM中,该信息会调用didEndDisplayingCell具有新的空数据源的tableView崩溃。

所以我经常抛出异常 Index out of range

我已经试过了:

func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {

    do {
        let imageMessageBody = msgSections[indexPath.section].msg[indexPath.row] as? ImageMessageBody
        let cell = tableView.dequeueReusableCellWithIdentifier("ImageUploadCell", forIndexPath: indexPath) as! ImageCell
        cell.willEndDisplayingCell()
    } catch {
        print("Swift try catch is confusing...")
    }
}

我也尝试过这个:

func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
    print(indexPath.section)
    print(indexPath.row)

    if msgSections.count != 0 {
        if let msg = msgSections[indexPath.section].msg[indexPath.row] as? ImageMessageBody {
            let cell = tableView.dequeueReusableCellWithIdentifier("ImageUploadCell", forIndexPath: indexPath) as! ImageCell
            cell.willEndDisplayingCell()
        }
    }
}

这是一个优先级很低的代码块,我花了大量的时间进行反复试验,弄清楚swift内置的错误处理程序可用于在我有无数种情况(如这种情况)的极端情况下代码可能会崩溃,并且不会对用户体验产生任何影响。

简而言之,我不需要任何花哨的东西,但是Swift似乎具有非常具体的错误处理程序,这些错误处理程序根据我是从函数返回值中获取值还是从数组索引中获取不存在的值而有所不同。

是否像其他流行编程语言一样,可以在Swift上进行简单尝试?


阅读 299

收藏
2020-07-07

共1个答案

一尘不染

正如评论和其他答案中所建议的那样,最好避免这种情况。但是,在某些情况下,您可能需要检查数组中是否存在某个项目以及是否确实将其返回。为此,您可以使用下面的Array扩展名来安全地返回数组项。

迅捷3

extension Collection where Indices.Iterator.Element == Index {
    subscript (safe index: Index) -> Generator.Element? {
        return indices.contains(index) ? self[index] : nil
    }
}

迅捷2

extension Array {
    subscript (safe index: Int) -> Element? {
        return indices ~= index ? self[index] : nil
    }
}
  • 这样你永远 不会打 Index out of range
  • 您必须检查项目是否为 nil

当我让ar = [1,3,4],然后让v = ar [5]时,在Xcode
8.3.2的Playground中尝试Swift3代码仍然会导致“崩溃”。为什么?–托马斯·滕佩尔曼5月17日17:40

你必须使用我们定制的标所以不是let v = ar[5],它是无线本地环路let v = ar[safe: 5]

从数组默认获取值。

let boo = foo[index]

添加使用自定义下标。

let boo = fee[safe: index]

// And we can warp the result using guard to keep the code going without throwing the exception.
guard let boo = foo[safe: index] else {
  return
}
2020-07-07