Swift錯(cuò)誤處理

定義

錯(cuò)誤處理是響應(yīng)錯(cuò)誤以及從錯(cuò)誤中回復(fù)的過程,那這個(gè)過程包括拋出、捕獲铡俐、傳遞和操作可恢復(fù)錯(cuò)誤的支持。

討論

有些操作可能無法在所有的狀態(tài)中都能返回一個(gè)有意義的值妥粟,當(dāng)然可選類型可以幫忙表示失敗的結(jié)果审丘,但是錯(cuò)誤處理可以讓你更好的理解錯(cuò)誤原因。
swift關(guān)于錯(cuò)誤處理的是協(xié)議Error勾给,這個(gè)是一個(gè)控協(xié)議滩报,可以通過枚舉結(jié)構(gòu)體遵循這個(gè)協(xié)議來實(shí)現(xiàn)錯(cuò)誤處理。

swift的異常處理有四種方式

  • 通過函數(shù)的方式傳遞下去
  • do-try-catch方式捕獲
  • try播急?將錯(cuò)誤作為可選性處理脓钾,錯(cuò)誤時(shí)返回nil。
  • try桩警! 斷言錯(cuò)誤不會(huì)發(fā)生可训,但是如果發(fā)生了會(huì)有運(yùn)行時(shí)錯(cuò)誤。

例子

舉個(gè)自動(dòng)販賣機(jī)的例子捶枢。當(dāng)我們?nèi)プ詣?dòng)販賣機(jī)買東西的時(shí)候握截,可能遇到以下問題

enum VendingMachineError:Error{
    case invalidSelection //選擇無效
    case insufficientFunds(coinsNeeded:Int) //金額不足
    case outOfStock       //缺貨
}

接下來我們創(chuàng)建一個(gè)自動(dòng)販賣機(jī)類型

//商品結(jié)構(gòu)體
struct Item{
    var price: Int
    var count: Int
}
//自動(dòng)販賣機(jī)
class VendingMachine{
    var inventory = [
        "Candy Bar" : Item(price: 12, count: 7),
        "Chips" : Item(price: 10, count: 4),
        "Pretzels" : Item(price: 7, count: 4)
    ]
    var coinsDesposited = 2
    func vend(itemNamed name:String )throws {
        guard let item = inventory[name] else{
            throw VendingMachineError.invalidSelection
        }
        guard item.count > 0 else {
            throw VendingMachineError.outOfStock
        }
        guard item.price <= coinsDesposited else {
            throw VendingMachineError.insufficientFunds(coinsNeeded: item.price-coinsDesposited)
        }
        var newItem = item
        newItem.count -= 1
        inventory[name] = newItem
        
        print("dispensing\(name)")
    }
}

由上可知,我們分別檢驗(yàn)商品是否存在烂叔,庫(kù)存是否充足以及投幣是否足夠谨胞。如果不滿足就拋出異常。下面我們分別看一下上面說過的四種錯(cuò)誤處理方式蒜鸡。
可以看出在函數(shù)體后胯努,返回值之前添加throws關(guān)鍵字表明該方法可能拋出異常牢裳。

通過函數(shù)的方式傳遞下去

比如添加了一個(gè)購(gòu)買者姓名的屬性,通過try + 方法調(diào)用的方式可以將異常傳遞下去叶沛。

 func vend(itemNamed name:String ,buyerName:String)throws{
        self.buyerName = buyerName
        try vend(itemNamed: name)
    }

do-try-catch方式捕獲

var test = VendingMachine();
do {
    try test.vend(itemNamed: "Chips")
} catch VendingMachineError.invalidSelection {
    print("invalidSelection")
} catch VendingMachineError.outOfStock{
    print("outOfStock")
} catch VendingMachineError.insufficientFunds(let coinsNeeded){
    print("insufficientFunds\(coinsNeeded)")
}

通過do可以捕獲捕獲方法作用于內(nèi)拋出的異常蒲讯,catch可以以枚舉的方式處理。

try恬汁?將錯(cuò)誤作為可選性處理伶椿,錯(cuò)誤時(shí)返回nil。

let x = try? test.vend(itemNamed: "Chips")

通過try?的方式氓侧,當(dāng)排出異常的時(shí)候x值為nil脊另,正常可以返回一個(gè)可選型返回值约巷。

try偎痛! 斷言錯(cuò)誤不會(huì)發(fā)生,但是如果發(fā)生了會(huì)有運(yùn)行時(shí)錯(cuò)誤独郎。

let x = try踩麦! test.vend(itemNamed: "Chips")

當(dāng)我們斷言方法不會(huì)拋出異常的時(shí)候可以用try!拋出異常的時(shí)候會(huì)有運(yùn)行時(shí)錯(cuò)誤氓癌,比較危險(xiǎn)谓谦。

結(jié)構(gòu)體表示Error

有些時(shí)候我們要描述的錯(cuò)誤比較復(fù)雜,我們也可以用結(jié)構(gòu)體遵循Error協(xié)議去實(shí)現(xiàn)異常處理贪婉。
官方給出的例子,xml解析錯(cuò)誤

struct XMLParsingError: Error {
    enum ErrorKind {
        case invalidCharacter
        case mismatchedTag
        case internalError
    }

    let line: Int
    let column: Int
    let kind: ErrorKind
}

捕獲錯(cuò)誤

do {
    let xmlDoc = try parse(myXMLData)
} catch let e as XMLParsingError {
    print("Parsing error: \(e.kind) [\(e.line):\(e.column)]")
} catch {
    print("Other error: \(error)")
}

綜上swift中的錯(cuò)誤處理是非常靈活的反粥,可以用多種數(shù)據(jù)結(jié)構(gòu)描述錯(cuò)誤。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末疲迂,一起剝皮案震驚了整個(gè)濱河市才顿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌尤蒿,老刑警劉巖郑气,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異腰池,居然都是意外死亡尾组,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門示弓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來演怎,“玉大人,你說我怎么就攤上這事避乏。” “怎么了甘桑?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵拍皮,是天一觀的道長(zhǎng)歹叮。 經(jīng)常有香客問我,道長(zhǎng)铆帽,這世上最難降的妖魔是什么咆耿? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮爹橱,結(jié)果婚禮上萨螺,老公的妹妹穿的比我還像新娘。我一直安慰自己愧驱,他們只是感情好慰技,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著组砚,像睡著了一般吻商。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上糟红,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天艾帐,我揣著相機(jī)與錄音,去河邊找鬼盆偿。 笑死柒爸,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的事扭。 我是一名探鬼主播捎稚,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼句旱!你這毒婦竟也來了阳藻?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤谈撒,失蹤者是張志新(化名)和其女友劉穎腥泥,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體啃匿,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蛔外,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了溯乒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片夹厌。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖裆悄,靈堂內(nèi)的尸體忽然破棺而出矛纹,到底是詐尸還是另有隱情,我是刑警寧澤光稼,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布或南,位于F島的核電站孩等,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏采够。R本人自食惡果不足惜肄方,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蹬癌。 院中可真熱鬧权她,春花似錦、人聲如沸逝薪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽翼闽。三九已至拾徙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間感局,已是汗流浹背尼啡。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留询微,地道東北人崖瞭。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像撑毛,于是被迫代替她去往敵國(guó)和親书聚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355