3 回答

TA貢獻(xiàn)1828條經(jīng)驗(yàn) 獲得超13個贊
斯威夫特2和3
Swift 2中的情況發(fā)生了一些變化,因?yàn)橛幸环N新的錯誤處理機(jī)制,它與異常更相似但細(xì)節(jié)不同。
1.表明錯誤的可能性
如果函數(shù)/方法想要指示它可能拋出錯誤,它應(yīng)該包含這樣的throws
關(guān)鍵字
func summonDefaultDragon() throws -> Dragon
注意:函數(shù)實(shí)際上可以拋出的錯誤類型沒有規(guī)范。該聲明只是聲明該函數(shù)可以拋出任何實(shí)現(xiàn)ErrorType的類型的實(shí)例,或者根本不拋出。
2.調(diào)用可能引發(fā)錯誤的函數(shù)
為了調(diào)用函數(shù),你需要使用try關(guān)鍵字,就像這樣
try summonDefaultDragon()
這條線通常應(yīng)該像這樣存在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模式匹配的所有強(qiáng)大功能,因此您在這里非常靈活。
如果您正在使用自己標(biāo)記為throws
關(guān)鍵字的函數(shù)調(diào)用throw函數(shù),則可能決定傳播錯誤:
func fulfill(quest: Quest) throws { let dragon = try summonDefaultDragon() quest.ride(dragon)}
或者,您可以使用try?
以下方法調(diào)用throw函數(shù):
let dragonOrNil = try? summonDefaultDragon()
這樣,如果發(fā)生任何錯誤,您將獲得返回值或nil。使用這種方式,您不會得到錯誤對象。
這意味著您還可以結(jié)合try?
有用的語句,例如:
if let dragon = try? summonDefaultDragon()
要么
guard let dragon = try? summonDefaultDragon() else { ... }
最后,您可以決定是否知道實(shí)際上不會發(fā)生錯誤(例如,因?yàn)槟呀?jīng)檢查過先決條件)并使用try!
關(guān)鍵字:
let dragon = try! summonDefaultDragon()
如果函數(shù)實(shí)際拋出錯誤,那么您將在應(yīng)用程序中收到運(yùn)行時錯誤,應(yīng)用程序?qū)⒔K止。
3.拋出錯誤
為了拋出錯誤,你可以像這樣使用throw關(guān)鍵字
throw DragonError.dragonIsMissing
你可以扔任何符合ErrorType
協(xié)議的東西。對于初學(xué)者來說NSError
,這符合這個協(xié)議,但你可能希望使用基于enum的方法ErrorType
,這樣你就可以將多個相關(guān)的錯誤分組,可能還有額外的數(shù)據(jù),比如這個
enum DragonError: ErrorType { case dragonIsMissing case notEnoughMana(requiredMana: Int) ...}
新的Swift 2和3錯誤機(jī)制與Java / C#/ C ++樣式異常之間的主要區(qū)別如下:
語法有點(diǎn)不同:
do-catch
+try
+defer
vs傳統(tǒng)try-catch-finally
語法。異常處理通常會在異常路徑中產(chǎn)生比在成功路徑中高得多的執(zhí)行時間。Swift 2.0錯誤的情況并非如此,其中成功路徑和錯誤路徑的成本大致相同。
必須聲明所有錯誤拋出代碼,而異??赡軓娜魏蔚胤綊伋觥K绣e誤都是Java命名法中的“已檢查異?!?。但是,與Java相比,您不指定可能拋出的錯誤。
Swift異常與ObjC異常不兼容。您的
do-catch
塊不會捕獲任何NSException,反之亦然,因?yàn)槟仨毷褂肙bjC。Swift異常與
NSError
返回false
(Bool
返回函數(shù))或nil
(AnyObject
返回函數(shù))和傳遞NSErrorPointer
錯誤詳細(xì)信息的Cocoa 方法約定兼容。
作為一種額外的合成糖來緩解錯誤處理,還有兩個概念
延遲動作(使用
defer
關(guān)鍵字),它可以實(shí)現(xiàn)與Java / C#/ etc中的finally塊相同的效果保護(hù)語句(使用
guard
關(guān)鍵字),它可以讓你寫的if / else代碼少于正常的錯誤檢查/信令代碼。
斯威夫特1
運(yùn)行時錯誤:
正如Leandros建議處理運(yùn)行時錯誤(如網(wǎng)絡(luò)連接問題,解析數(shù)據(jù),打開文件等),你應(yīng)該NSError
像在ObjC中那樣使用,因?yàn)镕oundation,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") })
仍然是故障塊經(jīng)常收到NSError
實(shí)例,描述錯誤。
程序員錯誤:
對于程序員錯誤(如數(shù)組元素的越界訪問,傳遞給函數(shù)調(diào)用的無效參數(shù)等),您在ObjC中使用了異常。雨燕語言似乎并未有任何異常的語言支持(如throw
,catch
等關(guān)鍵字)。但是,正如文檔所示,它與ObjC在同一運(yùn)行時運(yùn)行,因此您仍然可以NSExceptions
像這樣拋出:
NSException(name: "SomeName", reason: "SomeReason", userInfo: nil).raise()
雖然您可以選擇在ObjC代碼中捕獲異常,但您無法在純Swift中捕獲它們。
問題是你是否應(yīng)該拋出程序員錯誤的異常,或者更確切地說使用Apple在語言指南中建議的斷言。

TA貢獻(xiàn)2065條經(jīng)驗(yàn) 獲得超14個贊
Swift中沒有Exceptions,類似于Objective-C的方法。
在開發(fā)過程中,您可以assert
用來捕獲可能出現(xiàn)的任何錯誤,并且需要在投入生產(chǎn)之前進(jìn)行修復(fù)。
經(jīng)典的NSError
方法沒有改變,你發(fā)送一個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 關(guān)注
- 706 瀏覽
添加回答
舉報