如何捕获“索引超出范围”?在斯威夫特? [英] How do I catch "Index out of range" in Swift?

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

问题描述

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



我只需要:

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

这是我的困境,当TableView重新加载新数据时,一些信息是仍然选择在RAM中调用 didEndDisplayingCell 在一个tableView上,新的空数据源崩溃。



所以我经常抛出异常索引超出范围



我试过这个:

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

do {
let imageMes​​sageBody = msgSections [indexPath.section] .msg [indexPath.row]为? ImageMes​​sageBody
让cell = tableView.dequeueReusableCellWithIdentifier(ImageUploadCell,forIndexPath:indexPath)为! ImageCell
cell.willEndDisplayingCell()
} catch {
print(Swift try catch令人困惑......)
}
}

我也试过这个:

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

如果msgSections.count!= 0 {
如果让msg = msgSections [indexPath.section] .msg [indexPath.row]为? ImageMes​​sageBody {
让cell = tableView.dequeueReusableCellWithIdentifier(ImageUploadCell,forIndexPath:indexPath)为! ImageCell
cell.willEndDisplayingCell()
}
}
}

这是一个非常低优先级的代码块,我浪费了大量的时间进行试验和错误,弄清楚swift中构建的错误处理程序是什么,当我有大量场景时,这似乎是非常独特的情况像这样的代码可以崩溃,它不会对用户体验产生任何影响。



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



是否存在像所有其他流行的编程语言一样简单地尝试使用Swift吗?

解决方案

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



Swift 3

  extension Collection其中Indices.Iterator.Element ==索引{
下标(安全索引:索引) - > Generator.Element? {
返回indices.contains(索引)? self [index]:nil
}
}

Swift 2

  extension Array {
subscript(safe index:Int) - >元件? {
返回索引〜=索引? self [index]:nil
}
}




  • 这样你永远不会 索引超出范围

  • 你必须检查如果项目 nil



请参阅这个问题了解更多







在Xcode 8.3.2中的Playground中尝试使用Swift3代码仍然导致
崩溃,当我让ar = [1,3,4]时,然后让v = ar [5]。为什么? - Thomas
Tempelmann 5月17日17:40


你必须使用我们的自定义下标而不是让v = ar [5] ,它将是让v = ar [safe:5]



默认从数组中获取值。

  let boo = foo [ index] 

添加使用自定义下标。



< pre class =lang-swift prettyprint-override> let boo = fee [safe:index]

//我们可以使用guard来扭曲结果以保持代码运行没有抛出异常。
guard let boo = foo [safe:index] else {
return
}


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

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

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆