3 回答
TA贡献1828条经验 获得超13个赞
斯威夫特2和3
Swift 2中的情况发生了一些变化,因为有一种新的错误处理机制,它与异常更相似但细节不同。
1.表明错误的可能性
如果函数/方法想要指示它可能抛出错误,它应该包含这样的throws
关键字
func summonDefaultDragon() throws -> Dragon
注意:函数实际上可以抛出的错误类型没有规范。该声明只是声明该函数可以抛出任何实现ErrorType的类型的实例,或者根本不抛出。
2.调用可能引发错误的函数
为了调用函数,你需要使用try关键字,就像这样
try summonDefaultDragon()
这条线通常应该像这样存在do-catch块
do { let dragon = try summonDefaultDragon() } catch DragonError.dragonIsMissing { // Some specific-case error-handling} catch DragonError.notEnoughMana(let manaRequired) { // Other specific-case error-handlng} catch { // Catch all error-handling}
注意:catch子句使用Swift模式匹配的所有强大功能,因此您在这里非常灵活。
如果您正在使用自己标记为throws
关键字的函数调用throw函数,则可能决定传播错误:
func fulfill(quest: Quest) throws { let dragon = try summonDefaultDragon() quest.ride(dragon)}
或者,您可以使用try?
以下方法调用throw函数:
let dragonOrNil = try? summonDefaultDragon()
这样,如果发生任何错误,您将获得返回值或nil。使用这种方式,您不会得到错误对象。
这意味着您还可以结合try?
有用的语句,例如:
if let dragon = try? summonDefaultDragon()
要么
guard let dragon = try? summonDefaultDragon() else { ... }
最后,您可以决定是否知道实际上不会发生错误(例如,因为您已经检查过先决条件)并使用try!
关键字:
let dragon = try! summonDefaultDragon()
如果函数实际抛出错误,那么您将在应用程序中收到运行时错误,应用程序将终止。
3.抛出错误
为了抛出错误,你可以像这样使用throw关键字
throw DragonError.dragonIsMissing
你可以扔任何符合ErrorType
协议的东西。对于初学者来说NSError
,这符合这个协议,但你可能希望使用基于enum的方法ErrorType
,这样你就可以将多个相关的错误分组,可能还有额外的数据,比如这个
enum DragonError: ErrorType { case dragonIsMissing case notEnoughMana(requiredMana: Int) ...}
新的Swift 2和3错误机制与Java / C#/ C ++样式异常之间的主要区别如下:
语法有点不同:
do-catch
+try
+defer
vs传统try-catch-finally
语法。异常处理通常会在异常路径中产生比在成功路径中高得多的执行时间。Swift 2.0错误的情况并非如此,其中成功路径和错误路径的成本大致相同。
必须声明所有错误抛出代码,而异常可能从任何地方抛出。所有错误都是Java命名法中的“已检查异常”。但是,与Java相比,您不指定可能抛出的错误。
Swift异常与ObjC异常不兼容。您的
do-catch
块不会捕获任何NSException,反之亦然,因为您必须使用ObjC。Swift异常与
NSError
返回false
(Bool
返回函数)或nil
(AnyObject
返回函数)和传递NSErrorPointer
错误详细信息的Cocoa 方法约定兼容。
作为一种额外的合成糖来缓解错误处理,还有两个概念
延迟动作(使用
defer
关键字),它可以实现与Java / C#/ etc中的finally块相同的效果保护语句(使用
guard
关键字),它可以让你写的if / else代码少于正常的错误检查/信令代码。
斯威夫特1
运行时错误:
正如Leandros建议处理运行时错误(如网络连接问题,解析数据,打开文件等),你应该NSError
像在ObjC中那样使用,因为Foundation,AppKit,UIKit等以这种方式报告错误。所以它比语言事物更具框架性。
正在使用的另一种常见模式是AFNetworking中的分隔符成功/失败块:
var sessionManager = AFHTTPSessionManager(baseURL: NSURL(string: "yavin4.yavin.planets"))sessionManager.HEAD("/api/destoryDeathStar", parameters: xwingSquad, success: { (NSURLSessionDataTask) -> Void in println("Success") }, failure:{ (NSURLSessionDataTask, NSError) -> Void in println("Failure") })
仍然是故障块经常收到NSError
实例,描述错误。
程序员错误:
对于程序员错误(如数组元素的越界访问,传递给函数调用的无效参数等),您在ObjC中使用了异常。雨燕语言似乎并未有任何异常的语言支持(如throw
,catch
等关键字)。但是,正如文档所示,它与ObjC在同一运行时运行,因此您仍然可以NSExceptions
像这样抛出:
NSException(name: "SomeName", reason: "SomeReason", userInfo: nil).raise()
虽然您可以选择在ObjC代码中捕获异常,但您无法在纯Swift中捕获它们。
问题是你是否应该抛出程序员错误的异常,或者更确切地说使用Apple在语言指南中建议的断言。
TA贡献2065条经验 获得超14个赞
Swift中没有Exceptions,类似于Objective-C的方法。
在开发过程中,您可以assert
用来捕获可能出现的任何错误,并且需要在投入生产之前进行修复。
经典的NSError
方法没有改变,你发送一个NSErrorPointer
,填充。
简要示例:
var error: NSError?var contents = NSFileManager.defaultManager().contentsOfDirectoryAtPath("/Users/leandros", error: &error)if let error = error { println("An error occurred \(error)")} else { println("Contents: \(contents)")}
- 3 回答
- 0 关注
- 677 浏览
添加回答
举报