如何捕获“索引超出范围"?在斯威夫特?

How do I catch quot;Index out of rangequot; in Swift?(如何捕获“索引超出范围?在斯威夫特?)

本文介绍了如何捕获“索引超出范围"?在斯威夫特?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我只需要:

试试{//一些导致崩溃的代码.}抓住 {//好吧,崩溃了,所以让我们忽略这个块并继续前进.}

这是我的困境,当 TableView 重新加载新数据时,一些信息仍位于 RAM 中,这会在具有新空数据源的 tableView 上调用 didEndDisplayingCell 崩溃.

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

我试过了:

func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {做 {让 imageMes​​sageBody = msgSections[indexPath.section].msg[indexPath.row] 作为?图像消息体让 cell = tableView.dequeueReusableCellWithIdentifier("ImageUploadCell", forIndexPath: indexPath) as!图像单元cell.willEndDisplayingCell()} 抓住 {print("Swift try catch 令人困惑...")}}

我也试过这个:

func tableView(tableView: UITableView, didEndDisplayingCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {打印(indexPath.section)打印(indexPath.row)如果 msgSections.count != 0 {如果让 msg = msgSections[indexPath.section].msg[indexPath.row] 为?ImageMes​​sageBody {让 cell = tableView.dequeueReusableCellWithIdentifier("ImageUploadCell", forIndexPath: indexPath) as!图像单元cell.willEndDisplayingCell()}}}

这是一个非常低优先级的代码块,我已经浪费了很多时间来试错,以确定 swift 内置的哪个错误处理程序适用于似乎非常独特的情况,当我有大量的场景时,比如这是代码可能崩溃的地方,它不会对用户体验产生任何影响.

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

是否像其他所有流行的编程语言一样在 Swift 上进行简单的 try catch?

解决方案

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

斯威夫特 5

extension Collection where Indices.Iterator.Element == Index {下标(安全索引:索引)->迭代器.元素?{返回 index.contains(index) ?自我[索引]:无}}

Generator.Element 变成 Iterator.Element

斯威夫特 3

extension Collection where Indices.Iterator.Element == Index {下标(安全索引:索引)->生成器.元素?{返回 index.contains(index) ?自我[索引]:无}}

斯威夫特 2

扩展数组{下标(安全索引:Int)->元素?{返回索引〜=索引?自我[索引]:无}}

  • 这样你就永远不会命中 索引超出范围
  • 您必须检查项目是否为 nil

更多信息请参考这个问题


<块引用>

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

你必须使用我们自定义的下标,所以不是 let v = ar[5],而是 let v = ar[safe: 5].p>

默认从数组中获取值.

让 boo = foo[index]

添加使用自定义下标.

let boo = fee[safe: index]//我们可以使用 guard 来扭曲结果以保持代码继续运行而不会引发异常.守卫让 boo = foo[safe: index] else {返回}

I would really like to use a more simple classic try catch block in my Swift code but I can't find anything that does it.

I just need:

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

Here's my dilema, when the TableView is reloaded with new data, some information is still siting in RAM which calls didEndDisplayingCell on a tableView with a freshly empty datasource to crash.

So I frequently thrown the exception Index out of range

I've tried this:

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...")
    }
}

I've also tried this:

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()
        }
    }
}

This is a very low priority block of code, and I have wasted a lot of time with trial and error figuring out which error handler built into swift works for what seems to be extremely unique situations when I have tons of scenarios just like this one where the code can crash and it will not have any effect on the user experience.

In short, I don't need anything fancy but Swift seems to have extremely specific error handlers that differ based on whether I'm getting a value from a functions return value or getting a value from an array's index which may not exist.

Is there a simple try catch on Swift like every other popular programming language?

解决方案

As suggested in comments and other answers it is better to avoid this kind of situations. However, in some cases you might want to check if an item exists in an array and if it does safely return it. For this you can use the below Array extension for safely returning an array item.

Swift 5

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

Generator.Element becomes Iterator.Element

Swift 3

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

Swift 2

extension Array {
    subscript (safe index: Int) -> Element? {
        return indices ~= index ? self[index] : nil
    }
}

  • This way you'll never hit Index out of range
  • You'll have to check if the item is nil

refer this question for more


Trying the Swift3 code in a Playground in Xcode 8.3.2 still leads to a "crash" when I do let ar = [1,3,4], then let v = ar[5]. Why? – Thomas Tempelmann May 17 at 17:40

You have to use our customized subscript so instead of let v = ar[5], it wll be let v = ar[safe: 5].

Default getting value from array.

let boo = foo[index]

Add use the customized subscript.

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
}

这篇关于如何捕获“索引超出范围"?在斯威夫特?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本文标题为:如何捕获“索引超出范围"?在斯威夫特?

基础教程推荐