国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 編程 > Swift > 正文

窺探Swift編程中的錯(cuò)誤處理與異常拋出

2020-03-09 17:49:07
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友
本文給大家整理些關(guān)于Swift編程中的錯(cuò)誤處理與異常拋出,本文介紹的非常詳細(xì),基于參考價(jià)值,特此分享VEVB武林網(wǎng)平臺(tái)供大家學(xué)習(xí)
 

在Swift 2.0版本中,Swift語(yǔ)言對(duì)其錯(cuò)誤處理進(jìn)行了新的設(shè)計(jì),當(dāng)然了,重新設(shè)計(jì)后的結(jié)果使得該錯(cuò)誤處理系統(tǒng)用起來(lái)更爽。今天的主題就是系統(tǒng)的搞一下Swift中的錯(cuò)誤處理,以及看一下Swift中是如何拋出異常的。在編譯型語(yǔ)言中,錯(cuò)誤一般分為編譯錯(cuò)誤和運(yùn)行時(shí)錯(cuò)誤。我們平時(shí)在代碼中處理的錯(cuò)誤為運(yùn)行時(shí)錯(cuò)誤,我們對(duì)異常進(jìn)行處理的操作的目的是為了防止程序出現(xiàn)錯(cuò)誤而導(dǎo)致其他的副作用,比如用戶數(shù)據(jù)未保存等等。

在今天的文章中,先給出主動(dòng)產(chǎn)生異常的幾種情況,然后再給出如何處理被動(dòng)異常。

一、主動(dòng)退出程序的幾種情況

在Objective-C中,在單元測(cè)試時(shí)我們會(huì)使用斷言,斷言中條件滿足時(shí)會(huì)產(chǎn)生異常,并打印出相應(yīng)的斷言錯(cuò)誤,在Swift中也有幾種產(chǎn)生異常的語(yǔ)法。在本篇博客的第一部分就給出這幾種方法。

1.Fatal Errors(致命的錯(cuò)誤)

使用fatalError()函數(shù)可以立即終止你的應(yīng)用程序,在fatalError()中可以給出終止信息。使用fatalError()函數(shù),會(huì)毫無(wú)條件的終止你的應(yīng)用程序,用起來(lái)也是比較簡(jiǎn)單的,就是一個(gè)函數(shù)的調(diào)用。下方這個(gè)Demo一目了然呢,在此就不做過(guò)多贅述了。

窺探Swift編程中的錯(cuò)誤處理與異常拋出

2. Assertions(斷言)

在單元測(cè)試中是少不了斷言的,Swift中的斷言和Objective-C的區(qū)別不是太大,使用方法也是大同小異。下方就是斷言的兩種方法,由代碼提示可知,在斷言中的提示條件是可選的。斷言會(huì)在Debug模式下起作用,但是在Release版本中就會(huì)被忽略。

窺探Swift編程中的錯(cuò)誤處理與異常拋出

在assert()函數(shù)中, 第一個(gè)參數(shù)是Bool類(lèi)型,第二個(gè)參數(shù)是輸出的信息。當(dāng)條件為true時(shí),斷言不執(zhí)行,相應(yīng)的斷言信息不打印。當(dāng)條件為false時(shí),斷言執(zhí)行,并且打印相應(yīng)的斷言信息。

窺探Swift編程中的錯(cuò)誤處理與異常拋出

assertionFailure()函數(shù)只有一個(gè)Message參數(shù),并且該參數(shù)也是可以省略的,assertionFailure()沒(méi)有條件。如下所示:

窺探Swift編程中的錯(cuò)誤處理與異常拋出

3. 先決條件(Preconditions)

Preconditions的用法和斷言一樣,不過(guò)有一點(diǎn)需要主要,Preconditions在debug和release模式下都會(huì)被執(zhí)行,除非使用–Ounchecked進(jìn)行編譯。下方截圖是代碼提示給出的Preconditions函數(shù)的提示,如下所示:

窺探Swift編程中的錯(cuò)誤處理與異常拋出

關(guān)于Preconditions的具體用法請(qǐng)參照斷言,和斷言用法一樣,在此就不做過(guò)多的贅述了。

二.Swift中的錯(cuò)誤處理

在Objective-C中,如果你處理過(guò)錯(cuò)誤的話,那么你將會(huì)對(duì)NSError很熟悉。在Swift中,如果你要定義你自己的錯(cuò)誤類(lèi)型,你只需要實(shí)現(xiàn)ErrorType協(xié)議即可。聲明完錯(cuò)誤類(lèi)型后,就可以在處理錯(cuò)誤拋出異常時(shí)使用自定義的錯(cuò)誤類(lèi)型了。下方將會(huì)一步步帶你走完Swift中的錯(cuò)誤處理的路程。

1.使用枚舉創(chuàng)建錯(cuò)誤類(lèi)型

(1).遵循ErrorType協(xié)議,自定義錯(cuò)誤類(lèi)型。下方定義了一個(gè)錯(cuò)誤類(lèi)型枚舉,該枚舉遵循了ErrorType協(xié)議,在接下來(lái)的代碼中我們將會(huì)使用這個(gè)MyCustomErrorType枚舉,錯(cuò)誤枚舉的實(shí)現(xiàn)如下所示:

 //定義錯(cuò)誤類(lèi)型 enum MyCustomErrorType: ErrorType { case ErrorReason case ErrorReason case ErrorReason } 

(2).在我們的函數(shù)定義時(shí)可以使用throws關(guān)鍵字,以及在函數(shù)中使用throw關(guān)鍵字對(duì)錯(cuò)誤進(jìn)行拋出,拋出的錯(cuò)誤類(lèi)型就可以使用上面我們自己定義的錯(cuò)誤類(lèi)型。下方函數(shù)就是一個(gè)可以拋出錯(cuò)誤的函數(shù),拋出的錯(cuò)誤就是我們?cè)谏厦婷杜e中所定義的類(lèi)型。具體代碼如下所示:

 func myThrowFunc() throws { let test:Int? = nil guard test != nil else { throw MyCustomErrorType.ErrorReason } }

(3).上面函數(shù)的功能是對(duì)錯(cuò)誤進(jìn)行拋出,接下來(lái)就該使用do-catch來(lái)處理拋出的錯(cuò)誤。使用try對(duì)錯(cuò)誤進(jìn)行捕捉,使用do-catch對(duì)錯(cuò)誤進(jìn)行處理。具體處理方式如下所示。在下方錯(cuò)誤處理中類(lèi)似于switch-case語(yǔ)句,catch后邊可以枚舉匹配錯(cuò)誤類(lèi)型,具體如下所示:    

窺探Swift編程中的錯(cuò)誤處理與異常拋出

(4)在枚舉實(shí)現(xiàn)錯(cuò)誤類(lèi)型中我們可以通過(guò)值綁定的形式為錯(cuò)誤添加錯(cuò)誤代碼和錯(cuò)誤原因。在聲明枚舉時(shí),我們使用了枚舉元素值綁定的特性(關(guān)于枚舉使用的更多細(xì)節(jié)請(qǐng)參考之前的博客《窺探Swift之別樣的枚舉類(lèi)型》)。在聲明枚舉成員ErrorState時(shí),我們?yōu)槠浣壎藘蓚€(gè)變量,一個(gè)是錯(cuò)誤代碼errorCode, 另一個(gè)是錯(cuò)誤原因errorReason。這兩者可以在拋出錯(cuò)誤時(shí)為其傳入相應(yīng)的值,如下方代碼片段中的throwError函數(shù)所示,在拋出錯(cuò)誤是為errorCode指定的錯(cuò)誤代碼為404,為errorReason指定的錯(cuò)誤原因是“not found”。

  最后就是使用do-catch處理異常了,在catch中對(duì)綁定的錯(cuò)誤代碼和錯(cuò)誤原因進(jìn)行了獲取,并且通過(guò)where子句進(jìn)行了錯(cuò)誤代碼的篩選。此處catch的用法與switch-case中獲取枚舉綁定值的用法是一樣的,所以在此就不做過(guò)多的贅述。具體實(shí)現(xiàn)方式如下代碼所示:

窺探Swift編程中的錯(cuò)誤處理與異常拋出

2.使用結(jié)構(gòu)體為錯(cuò)誤處理添加Reason

在上面的內(nèi)容中,使用枚舉遵循ErrorType協(xié)議的方式定義了特定的錯(cuò)誤類(lèi)型。接下來(lái)我們將使用結(jié)構(gòu)體來(lái)遵循ErrorType協(xié)議,為錯(cuò)誤類(lèi)型添加錯(cuò)誤原因。也就是說(shuō),我們可以在拋出錯(cuò)誤時(shí),給自定義錯(cuò)誤類(lèi)型提供錯(cuò)誤原因。該功能在開(kāi)發(fā)中是非常常用的,而且用起來(lái)也是非常爽的。接下來(lái)就看一下如何為我們的錯(cuò)誤類(lèi)型添加錯(cuò)誤原因。

(1)使用結(jié)構(gòu)體創(chuàng)建錯(cuò)誤類(lèi)型,下方名為MyErrorType的結(jié)構(gòu)體遵循了ErrorType協(xié)議,并且在MyErrorType結(jié)構(gòu)體中,聲明了一個(gè)reason常量,該reason常量中存儲(chǔ)的就是錯(cuò)誤原因,具體實(shí)現(xiàn)方式如下:

 struct MyErrorType: ErrorType { let reason : String }

(2)上面定義完錯(cuò)誤類(lèi)型結(jié)構(gòu)體后,在錯(cuò)誤拋出中就可以使用了。在錯(cuò)誤拋出時(shí),可以傳入一個(gè)錯(cuò)誤原因,具體代碼如下所示:

 func myThrowFunc() throws { let test:Int? = nil guard test != nil else { throw MyErrorType(reason: "我是詳細(xì)的錯(cuò)誤原因,存儲(chǔ)在error中") } } 

(3)最后要對(duì)拋出的錯(cuò)誤進(jìn)行do-catch處理,在處理時(shí),可以對(duì)錯(cuò)誤原因進(jìn)行打印,錯(cuò)誤原因存儲(chǔ)在error中,具體操作和打印結(jié)果如下所示:      

窺探Swift編程中的錯(cuò)誤處理與異常拋出

由上面的輸出結(jié)果可知,error是我們自定義的MyErrorType類(lèi)型,我們可以使用下面的代碼來(lái)代替catch中的print語(yǔ)句,如下所示:    

窺探Swift編程中的錯(cuò)誤處理與異常拋出

上面的做法似乎有些麻煩,還有一種簡(jiǎn)化輸出的方法,就是在上述結(jié)構(gòu)體中實(shí)現(xiàn)CustomDebugStringConvertible協(xié)議,對(duì)描述信息進(jìn)行一個(gè)重寫(xiě),就可以在打印error時(shí),只打印錯(cuò)誤信息,下方是重寫(xiě)后的結(jié)構(gòu)體。   

 struct MyErrorType: ErrorType,CustomDebugStringConvertible { let reason : String var debugDescription: String { return "錯(cuò)誤類(lèi)型-----/(self.dynamicType): /(reason)" } } 

修改后,輸出結(jié)果如下,直接打印error輸出的就是錯(cuò)誤信息,而不是MyErrorType類(lèi)型。

窺探Swift編程中的錯(cuò)誤處理與異常拋出

3.使String類(lèi)型遵循ErrorType協(xié)議,直接使用String提供錯(cuò)誤原因

在“2”中,我們使用了結(jié)構(gòu)體遵循ErrorType協(xié)議的形式,來(lái)為錯(cuò)誤提供錯(cuò)誤信息的。在接下來(lái)的部分,我們將通過(guò)更為簡(jiǎn)單的方式為拋出的錯(cuò)誤提供錯(cuò)誤信息。這種方式更為簡(jiǎn)單,也易于理解,具體方式如下方代碼所示:    

窺探Swift編程中的錯(cuò)誤處理與異常拋出

三、在錯(cuò)誤處理中使用內(nèi)置關(guān)鍵字

1.初探這些內(nèi)置關(guān)鍵字

在Swift中提供了一些內(nèi)置關(guān)鍵字(__FILE__, __FUNCTION__, __LINE__等)來(lái)獲取上下文信息,在本篇博客的第三部分,將會(huì)給出如何在我們的錯(cuò)誤處理中使用這些內(nèi)置關(guān)鍵字。下方就是這些內(nèi)置關(guān)鍵字的作用,如下所示:

窺探Swift編程中的錯(cuò)誤處理與異常拋出

上面說(shuō)是內(nèi)置關(guān)鍵字,其實(shí)就是存儲(chǔ)代碼上下文的宏定義,上方代碼段簡(jiǎn)單的給出了這些內(nèi)置關(guān)鍵字的作用與用法,在接下來(lái)將在ErrorType中使用這些內(nèi)置關(guān)鍵字,讓我們的錯(cuò)誤信息更加豐富多彩。 

2.在ErrorType中使用上述內(nèi)置關(guān)鍵字

如果想在ErrorType中使用這些上下文內(nèi)置關(guān)鍵字,我們只需要對(duì)ErrorType進(jìn)行擴(kuò)展,使其在ErrorType提供錯(cuò)誤信息時(shí)給出出錯(cuò)的上下文信息。當(dāng)然,這實(shí)現(xiàn)起來(lái)比較簡(jiǎn)單,就是在ErrorType中添加了一個(gè)擴(kuò)展方法contextString()。該方法的作用就是提供錯(cuò)誤的上下文信息,也就是在出錯(cuò)的地方,調(diào)用contextString()方法生成上下文描述信息即可。對(duì)ErrorType協(xié)議的具體延展實(shí)現(xiàn)如下代碼段所示.

在下方代碼片段中,我們對(duì)ErrorType進(jìn)行了擴(kuò)展,為ErrorType添加了contextString的函數(shù)實(shí)現(xiàn)。contextString()函數(shù)有三個(gè)默認(rèn)參數(shù),分別是file--當(dāng)前文件名,function--當(dāng)前出錯(cuò)的函數(shù)名,line--當(dāng)前拋出異常的行數(shù)。上述三個(gè)參數(shù)都有參數(shù)默認(rèn)值,分別對(duì)應(yīng)著__FILE__, __FUNCTION__, __LINE__。該擴(kuò)展函數(shù)的返回值為這三個(gè)參數(shù)組成從字符串信息。具體實(shí)現(xiàn)如下所示:

窺探Swift編程中的錯(cuò)誤處理與異常拋出

3.使用擴(kuò)展的contextString方法

上面我們使用結(jié)構(gòu)體實(shí)現(xiàn)ErrorType協(xié)議的形式,為錯(cuò)誤類(lèi)型添加錯(cuò)誤原因。接下來(lái)我們將在添加reason的同時(shí),使用contextString()函數(shù)添加描述信息。下方CustomErrorType結(jié)構(gòu)體遵循了ErrorType協(xié)議,其中添加了一個(gè)reason常量來(lái)存儲(chǔ)錯(cuò)誤原因,一個(gè)context常量來(lái)存儲(chǔ)上下文信息,并且為該結(jié)構(gòu)體添加了一個(gè)構(gòu)造函數(shù),在構(gòu)造函數(shù)中初始化和reason常量。具體實(shí)現(xiàn)如下所示:  

窺探Swift編程中的錯(cuò)誤處理與異常拋出

4. 拋出并捕獲異常

在下方代碼中函數(shù)throwError()拋出了異常,該拋出的錯(cuò)誤類(lèi)型是CustomErrorType。在創(chuàng)建CustomErrorType類(lèi)型實(shí)例,也就是err變量時(shí),我們指定了錯(cuò)誤原因,也就是為reason賦了一個(gè)值。在創(chuàng)建完err實(shí)例后,我們又調(diào)用延展contextString()函數(shù)獲取異常的上下文信息,并把返回的內(nèi)容存儲(chǔ)在err實(shí)例的context屬性中。最后使用throw關(guān)鍵字拋出err實(shí)例,如下方第一部分代碼所示。

在創(chuàng)建拋出異常的函數(shù)后,我們需要對(duì)拋出的異常進(jìn)行捕獲。也就是使用try對(duì)異常進(jìn)行捕獲,使用do-catch對(duì)異常進(jìn)行處理,具體操作如下方第二段代碼所示。

   窺探Swift編程中的錯(cuò)誤處理與異常拋出 

5. 分析打印結(jié)果

經(jīng)過(guò)上述步驟如果你在Playground中進(jìn)行試驗(yàn)的,那么在控制臺(tái)上你將會(huì)看到如下信息。從打印出的信息我們可以看到,信息包括reason:錯(cuò)誤原因,和context:異常上下文。在下方的輸出結(jié)果中,文件名我們可以看到是<EXPR>這并不是確切的文件名,因?yàn)槲覀兪窃赑layground中使用的,并且不是確切的Swift源文件,所以獲取不到確切的文件名。

窺探Swift編程中的錯(cuò)誤處理與異常拋出

為了觀察確切的文件名,我們需要在確切的Swift源文件中拋出上述異常。在特定Swift源文件中,我們會(huì)看到下方的輸出結(jié)果。從下方的輸出日志中,我們可以清楚的看到文件名是一個(gè)詳細(xì)的文件路徑。如下所示:    

窺探Swift編程中的錯(cuò)誤處理與異常拋出

關(guān)于本文給大家介紹的Swift編程中的錯(cuò)誤處理與異常拋出就給大家介紹到這里,以后再做小demo時(shí),如何用到其他的錯(cuò)誤處理方式,在給大家詳解介紹。謝謝大家對(duì)VEVB武林網(wǎng)網(wǎng)站的支持!



注:相關(guān)教程知識(shí)閱讀請(qǐng)移步到swift教程頻道。
發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 昌邑市| 阿合奇县| 金堂县| 永顺县| 轮台县| 九江市| 张家川| 久治县| 贡嘎县| 新巴尔虎右旗| 长岭县| 陵川县| 西安市| 邹平县| 山东| 寿阳县| 五河县| 石首市| 肇庆市| 屏边| 北辰区| 阳曲县| 甘南县| 于都县| 静宁县| 台湾省| 永吉县| 土默特右旗| 陇西县| 韶关市| 庆云县| 北辰区| 平原县| 高雄市| 旌德县| 威信县| 临洮县| 台山市| 封开县| 通化市| 历史|