Swift--错误处理

do-try-catch错误处理模式

Swift2.x抛弃了cocoa的错误处理模式,使用了do-try-catch错误处理模式

cocoa的错误处理模式

let contents = NSString(contentsOfFile: filePath, encoding: NSUTF8StringEncoding, error: nil)

或者
var err: NSError?

let contents = NSString(contentsOfFile: filePath, encoding: NSUTF8StringEncoding, error: err)

由于Objective-C和Swift1.x没有强制处理机制,因此一旦真的发生错误,程序就会崩溃

do-try-catch错误模式

do {
    let str = try NSString(contentsOfFile: filePath, encoding: NSUTF8StringEncoding)

} catch let err as NSError {
    print(err.description)
}

: do-tyr-catch这种错误模式与Java中异常处理机制非常类似,本意就是尝试( try )做一件事情,如果失败则捕获( catch )处理

捕获错误

完整的do-try-catch错误处理模式语法如下:
do {
try 语句
成功处理语句组
} catch 匹配错误 {
错误处理语句组
}

错误类型

在Swift中错误类型必须遵从Error Type协议,其次是考虑错误类型的匹配,它应该设计为枚举类型,因为枚举类型非常适合将一组相关值关联起来。

enum DAOError: Error {
    case NOData
    case PrimaryKeyNull
}

do {
    //try 访问数据表函数或方法
} catch DAOError.NOData {
    print("没有数据。")
}catch DAOError.PrimaryKeyNull {
    print("主键为空。")
}
在函数或方法中抛出错误
  • 在函数或方法中通过throw语句人为地抛出错误
  • 在函数或方法中调用其他可以抛出错误的函数或方法,但是没有捕获处理,会导致错误被传播出来

//删除Note 方法
func remove(model: Note) throws {
    guard let date = model.data else {
        //抛出“主键为空”错误
        throw DAOError.PrimaryKeyNull
    }

    //比较日期主键是否相等
    for (index, note) in listData.enumerate() where note.date == date     {
        listData.removeIndex(index)
    }
}

//查询所有数据方法
func findAll() throws -> [Note] {
    guard listData.count > 0 else {
        //抛出“没有数据”错误
        throw DAOError.NoData
    }
  return listData
}

func printNotes() throws {
    let datas = try findAll()
    for note in datas {
        print("data: \(note.date!) - content:\(note.content!)")
    }
}

try printNotes()

1、remove方法我们声明为有可能发生错误,加了个throws, 如果 let date = model.date 成立的话,走for语句,否则抛出异常“ throw DAOError.PrimaryKeyNull”,跳出程序代码。
2、findAll方法我们声明为有可能发生错误,加了个throws, 有返回值[Note],如果“listData.count > 0” 成立,返回listData,否则抛出异常。
3、printNotes方法我们声明为有可能发生错误,加了个throws。
方法内部调用findAll方法,即在printNotes方法中调用了可以抛出错误的findAll方法,所以前面要加try,但却没有用catch捕获处理这个错误,一旦发生错误,捕获不到错误,方法不会继续往下走,跳出方法,往下传播,传播它的上层调用者,把错误给上层调用者,上层调用者还是处理不了的话,在往下传,最后传到运行环境,然后崩溃。

4、调用“try printNotes()” ,会调用printNotes方法, 调用printNotes方法又会调用findAll方法,如果findAll方法中有错误发生的情况下,错误传递给findAll方法,findAll方法又会传递给printNotes方法,然后再传递给“try printNotes”。如果“try printNotes”也不捕获的话就会传递给运行环境,运行环境遇到错误后就会崩掉。

对错误进行捕获和处理,并不是所有的函数和方法都有这个必要性,有的是没有这个必要性的,所以只能往上传播给它的调用者。有的函数和方法是需要捕获并处理的

比如一些权限的问题,有人有必要有能力来处理这个错误,把错误抛给他,他来处理。比如有些错误是给用户看的,有些是给管理员看的,如果是给用户看的错误要抛给表示层(view, viewController),如果是给系统管理员看的,直接打印日志,存到数据库里,或发个邮件就可以了。

声明抛出错误

能放到try后面调用的函数或方法都是有要求的,它们是有可能抛出错误,但你要在这些函数或方法声明的参数后面加上throws关键字,表示这个函数或方法可以抛出错误。

示例:

//删除Note记录的方法
func remove(model: Note) throws {
        ...
}

//查询所有记录数据的方法
func findAll() throws -> [Note] {
        ...
}
try? 和 try!的使用区别

1、使用try

try?会将错误转换为可选值,当调用try? + 函数或方法语句时,如果函数或方法抛出错误,程序不会崩溃,而是返回一个nil; 如果没有抛出错误,则返回可选值。

func findAll() throws -> [Note] {
    guard listData.count > 0 else {
        //抛出“没有数据”错误
        throw DAOError.NoData
    }
    return listData
}

 let datas = try? findAll()

  print(datas)

2、使用try!

使用try!可以打破错误传播链条。错误抛出后被传播者捕获,这样就形成了一个传播链条,有时我们确实不想让错误传播下去,这时便可以使用try!语句。

//查询所有数据方法
func findAll() throws -> [Note] {
    guard listData.count > 0 else {
        //抛出“没有数据”错误
        throw DAOError.NoData
    }
    return listData
}

func printNotes() {
    let datas = try! findAll()
    for note in datas {
        print("data: \(note.date!) - content:\(note.content!)")
    }
}

printNotes()
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,921评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,635评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,393评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,836评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,833评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,685评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,043评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,694评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,671评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,670评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,779评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,424评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,027评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,984评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,214评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,108评论 2 351
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,517评论 2 343