【问题标题】:Try Catch in Swift在 Swift 中尝试 Catch
【发布时间】:2017-02-13 17:12:06
【问题描述】:

我是一名 c# 开发人员,所以我非常习惯于将整个代码块包装在 try catch 中,写入事件日志然后不用担心它。

我只是无法快速解决问题

我正在使用 Kanna HTML/XML pod 来解析 html 页面并在表格中查找链接并提取它们。我是这样做的

enum MyError: Error {
    case FoundNil(String)
}

if let doc = Kanna.HTML(html: html, encoding: String.Encoding.utf8) 
{
    var count = 0
    //loop through all instances of <tr> in the html
    for row in doc.xpath("//tr") {
        var linkName = ""
        do{
            //get the <a> text from inside a <div> from the 2nd <td>
            if let name =  row?.xpath("//td[2]//div//a[1]")[count]
            {
                linkName = name.text
            }
            else{
                throw MyError.FoundNil("name")
            } 
            count = count + 1
        }
        catch{
            print("Error: \(error)")

        }
    }
}

问题是我并不总是知道在 xpath //td[2]//div//a[1] 的表格单元格中会有一个链接,所以它适用于前几行然后它崩溃出现致命错误,

致命错误:索引超出范围

它不会去catch或else

我也尝试过使用警卫,但也没有抛出

guard let name =  row?.xpath("//td[2]//div//a[1]")[count] else{
    throw MyError.FoundNil("name")
}

如果我需要检查 50 个表格单元格怎么办 我需要尝试一下吗?

【问题讨论】:

  • 您无法在 Swift 中捕获“索引超出范围”或其他运行时错误,请比较 stackoverflow.com/questions/38737880/…
  • 问题是fatal error: Index out of range 也不例外,它只是简单的消息崩溃。这是Objective C/Swift 1 的产物,那些fatalError 在stdlib 中无处不在,无法使用Swift 2+ do/catch 捕获。所以,欢迎来到iOS dev,你会经常看到这样的东西。
  • 谢谢,这解释了很多...回到绘图板

标签: swift try-catch


【解决方案1】:

如 cmets 中所述,您无法捕获运行时异常。

但您可以使用可选绑定并在一行中检查有效范围

if let name = row?.xpath("//td[2]//div//a[1]") where count < name.count {
  linkName = name[count].text
}

在 Swift 3 中,将 where 替换为逗号

【讨论】:

  • 会试试这个,我重新设计了一种不同的方式,所以我不再使用 count 来访问该行,所以不再超出范围,但这看起来如果我回到它会起作用[计数]
【解决方案2】:

我的回答只是指尝试...抓住...而且可能对其他人也有用。你可以这样做……

enum MyError: Error {
    case FoundNil(String)
}
do{
if let doc = Kanna.HTML(html: html, encoding: String.Encoding.utf8) 
{
    var count = 0
    //loop through all instances of <tr> in the html
    for row in doc.xpath("//tr") 
    {
        var linkName = ""

            //get the <a> text from inside a <div> from the 2nd <td>
            if let name =  row?.xpath("//td[2]//div//a[1]")[count]
            {
                linkName = name.text
            }
            else{
                throw MyError.FoundNil("name")
            } 
            count = count + 1
      }

}
}catch{
            print("Error: \(error)")

        }

如果您仍然需要任何帮助,请随时问我。

【讨论】:

  • 这不会捕获问题中的超出范围的异常。
【解决方案3】:

最后,我只是取出了所有的捕获并重新设计了我访问数据的方式,它似乎已经成功了 我不再使用 count 在行中移动,使用不同的 xpath 值,然后直接在活动行上工作,而不是我认为我在数组中的位置,我认为它只是 .在对所有内容进行排序的 xpath 的开头,就像在当前行上工作一样,所以我不需要 [count] 来获取它

let xpo = doc.xpath("//tr") as XPathObject
let xCount = xpo.count
var count = 0 
for row in xpo {
    if (count <= xCount){
        var linkName = ""

        for a in row.xpath(".//td[2]//div//a[1]")
        {
            linkName =  a.text
        }
    }
    count = count +1 
}

【讨论】:

    猜你喜欢
    • 2021-04-08
    • 2014-12-22
    • 2012-02-26
    • 2015-10-04
    • 2010-12-25
    • 2011-07-05
    • 1970-01-01
    • 1970-01-01
    • 2023-03-18
    相关资源
    最近更新 更多