首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Swift 2:调用可以抛出,但未标记为“try”,并且未处理错误

Swift 2:调用可以抛出,但未标记为“try”,并且未处理错误
EN

Stack Overflow用户
提问于 2015-06-10 00:03:17
回答 2查看 117.2K关注 0票数 171

在我安装了Xcode7测试版并将我的swift代码转换为Swift 2之后,我遇到了一些我无法解决的代码问题。我知道Swift 2是新的,所以我搜索并计算出,既然没有关于它的任何东西,我应该写一个问题。

这里是错误:

调用可以引发,但未标记为“try”,并且未处理错误

代码:

func deleteAccountDetail(){
        let entityDescription = NSEntityDescription.entityForName("AccountDetail", inManagedObjectContext: Context!)
        let request = NSFetchRequest()
        request.entity = entityDescription

        //The Line Below is where i expect the error
        let fetchedEntities = self.Context!.executeFetchRequest(request) as! [AccountDetail]

        for entity in fetchedEntities {
        self.Context!.deleteObject(entity)
        }

        do {
            try self.Context!.save()
        } catch _ {
        }

    }

快照:

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-06-10 00:12:34

您必须捕获错误,就像您已经对您的save()调用所做的那样,并且因为您在这里处理多个错误,所以您可以在单个do- try块中顺序地捕获多个调用,如下所示:

func deleteAccountDetail() {
    let entityDescription = NSEntityDescription.entityForName("AccountDetail", inManagedObjectContext: Context!)
    let request = NSFetchRequest()
    request.entity = entityDescription

    do {
        let fetchedEntities = try self.Context!.executeFetchRequest(request) as! [AccountDetail]

        for entity in fetchedEntities {
            self.Context!.deleteObject(entity)
        }

        try self.Context!.save()
    } catch {
        print(error)
    }
}

或者就像@bames53在下面的评论中指出的那样,通常更好的做法是不在抛出错误的地方捕捉它。您可以将该方法标记为throws,然后使用try调用该方法。例如:

func deleteAccountDetail() throws {
    let entityDescription = NSEntityDescription.entityForName("AccountDetail", inManagedObjectContext: Context!)
    let request = NSFetchRequest()

    request.entity = entityDescription

    let fetchedEntities = try Context.executeFetchRequest(request) as! [AccountDetail]

    for entity in fetchedEntities {
        self.Context!.deleteObject(entity)
    }

    try self.Context!.save()
}
票数 179
EN

Stack Overflow用户

发布于 2015-06-10 01:31:24

在Swift中调用使用throws声明的函数时,必须使用trytry!注释函数调用点。例如,给定一个抛出函数:

func willOnlyThrowIfTrue(value: Bool) throws {
  if value { throw someError }
}

这个函数可以像这样调用:

func foo(value: Bool) throws {
  try willOnlyThrowIfTrue(value)
}

在这里,我们使用try对调用进行注释,该调用向读者发出此函数可能抛出异常,并且后面的任何代码行都可能无法执行。我们还必须用throws注释这个函数,因为这个函数可能会抛出异常(即,当willOnlyThrowIfTrue()抛出时,foo会自动向上重新抛出异常。

如果你想调用一个被声明为可能抛出的函数,但你知道在你的情况下不会抛出这个函数,因为你给了它正确的输入,你可以使用try!

func bar() {
  try! willOnlyThrowIfTrue(false)
}

这样,当您保证代码不会抛出异常时,您就不必放入额外的样板代码来禁用异常传播。

try!是在运行时强制执行的:如果您使用try!,并且函数确实抛出了异常,那么您的程序的执行将因运行时错误而终止。

大多数异常处理代码应该类似于上面的代码:要么在异常发生时简单地向上传播异常,要么设置条件以排除其他可能的异常。对代码中其他资源的任何清理都应该通过对象销毁(即deinit())进行,有时也可以通过defered代码进行。

func baz(value: Bool) throws {

  var filePath = NSBundle.mainBundle().pathForResource("theFile", ofType:"txt")
  var data = NSData(contentsOfFile:filePath)

  try willOnlyThrowIfTrue(value)

  // data and filePath automatically cleaned up, even when an exception occurs.
}

如果出于某种原因,您清理了需要运行但不在deinit()函数中的代码,您可以使用defer

func qux(value: Bool) throws {
  defer {
    print("this code runs when the function exits, even when it exits by an exception")
  }

  try willOnlyThrowIfTrue(value)
}

大多数处理异常的代码只是让它们向上传播到调用者,通过deinit()defer在过程中进行清理。这是因为大多数代码不知道如何处理错误;它知道哪里出了问题,但它没有足够的信息来了解一些更高级别的代码正在尝试做什么,以便知道如何处理错误。它不知道向用户呈现对话框是否合适,或者是否应该重试,或者其他东西是否合适。

然而,更高级别的代码应该确切地知道在发生任何错误时该如何处理。因此,异常允许特定的错误从最初发生的地方到可以处理的地方冒泡。

异常处理是通过catch语句完成的。

func quux(value: Bool) {
  do {
    try willOnlyThrowIfTrue(value)
  } catch {
    // handle error
  }
}

可以有多个catch语句,每个语句捕获一种不同类型的异常。

  do {
    try someFunctionThatThowsDifferentExceptions()
  } catch MyErrorType.errorA {
    // handle errorA
  } catch MyErrorType.errorB {
    // handle errorB
  } catch {
    // handle other errors
  }

有关处理异常的最佳实践的更多详细信息,请参阅http://exceptionsafecode.com/。它是专门针对C++的,但在研究了Swift异常模型之后,我相信基本原理也适用于Swift。

有关Swift语法和错误处理模型的详细信息,请参阅一书。

票数 44
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/30737262

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档