swift3 错误处理

1.一般处理错误步骤:

1.使用 Error 建立异常类型

例:

//处理更细分的错误情况,错误类型须遵从Error协议
enum DogError : Error{
    case NameInvalidError
    case AgeInvalidError
    case NameLengthError
}

2.使用 throws 来声明异常,用 throw 来抛出异常

一个函数可以加上throws关键字,表示可以处理错误. 这个函数调用者可以捕获(catch)这个错误并进行应对.
如何抛出异常:

1.在抛出异常之前,我们需要在函数方法的返回箭头 -> 前使用 throws 来标明将会抛出异常
例:

//有返回值时
func myMethodRetrunString() throws -> String
//无返回值时
func myMethodRetrunNothing() throws

2.声明之后, 我们需要在函数或者方法里扔出异常,很简单使用throw 就可以了

3.使用 do-catch 机制来获取和处理throw抛出的异常

用 Do-Catch 处理错误:
可以使用一个do-catch语句运行一段闭包代码来处理错误。如果在do子句中的代码抛出了一个错误,这个错误会与catch子句做匹配,从而决定哪条子句能处理它。
下面是do-catch语句的一般形式:

do {
 try expression
 statements
 } catch pattern 1 {
 statements
 } catch pattern 2 where condition {
 statements
 }

4.当你调用可以抛出错误函数,须在前面加上try关键字.

do{
    //当你调用可以抛出错误函数,须在前面加上try关键字.
    try str = myDog.printDogMessage(dog: myDog)
}
catch {
    switch (error){
    case DogError.NameInvalidError: print("dog的名字无效错误")
    case DogError.NameLengthError : print("dog的名字长度错误")
    case DogError.AgeInvalidError : print("dog的年龄设置不合法")
    default:print("Main:捕获到dog其他错误")
    }
}

Demo:

//处理更细分的错误情况,错误类型须遵从Error协议
enum DogError : Error{
    case NameInvalidError
    case AgeInvalidError
    case NameLengthError
}

import UIKit
//NSObject需添加UIKit
class Dog: NSObject {
    var name : String!
    var age : Int!
    init(name:String,age:Int){
        self.name = name
        self.age = age
    }

    //一个函数可以加上throws关键字,表示可以处理错误. 这个函数调用者可以捕获(catch)这个错误并进行应对.
    //使用 throws 来声明异常,用 throw 来抛出异常
    func printDogMessage(dog:Dog) throws -> String{
        print("Dog-Class:开始检查名字是否无效")
        //guard语句判断其后的表达式布尔值为false时,才会执行之后代码块里的代码,如果为true,则跳过整个guard语句.
        guard let name : String = dog.name else{
            throw DogError.NameInvalidError
        }
        print("Dog-Class:开始检查名字长度是否无效")
        if name.characters.count < 3{
            throw DogError.NameLengthError
        }
        print("Dog-Class:开始检查年龄是否无效")
        if age < 0 || age > 20{
            throw DogError.AgeInvalidError
        }
        print("Dog-Class:返回信息")
        return "dog的信息为" + dog.name + "\(dog.age)"
    }  
}

调用错误处理方法代码:

方法1:直接do-catch调用

let myDog = Dog(name: "小白",age: 18)
var str : String!
do{
    //当你调用可以抛出错误函数,须在前面加上try关键字.
    try str = myDog.printDogMessage(dog: myDog)
}
catch {
    switch (error){
    case DogError.NameInvalidError: print("dog的名字无效错误")
    case DogError.NameLengthError : print("dog的名字长度错误")
    case DogError.AgeInvalidError : print("dog的年龄设置不合法")
    default:print("Main:捕获到dog其他错误")
    }
}
print("Main:最后输出为\(str)")
/*打印如下: Dog-Class:开始检查名字是否无效 Dog-Class:开始检查名字长度是否无效 dog的名字长度错误 Main:最后输出为nil */

方法2:包装do-catch方法调用

func testDogError(testdog:Dog){

    do{
        var teststr : String!
        try teststr = testdog.printDogMessage(dog: testdog)
        //只有正确时才会有返回值打印
        print("正确:\(teststr)")

    }
    catch {
        switch (error){
        case DogError.NameInvalidError: print("dog的名字无效错误")
        case DogError.NameLengthError : print("dog的名字长度错误")
        case DogError.AgeInvalidError : print("dog的年龄设置不合法")
        default:print("Main:捕获到dog其他错误")
        }
    }

}

let myDog1 = Dog(name: "小白兔",age: 30)
testDogError(testdog: myDog1)

let myDog2 = Dog(name: "小白狗",age: 18)
testDogError(testdog: myDog2)
/*打印如下: Dog-Class:开始检查名字是否无效 Dog-Class:开始检查名字长度是否无效 Dog-Class:开始检查年龄是否无效 dog的年龄设置不合法 Dog-Class:开始检查名字是否无效 Dog-Class:开始检查名字长度是否无效 Dog-Class:开始检查年龄是否无效 Dog-Class:返回信息 正确:Optional("dog的信息为小白狗Optional(18)") */

2. 不用do-catch的简便调用 try! 与 try?

try?与try! 方式的简便调用不用写do{}catch{}

1. try! 的使用

try! :这种写法适用确定一定会成功的情况,需要确定一定不会出现有异常抛出的情况,这种写法建议不要用或者少用。

let myDog4 = Dog(name: "小白狗",age: 18)
//try! ...这种写法适用确定一定会成功的情况,需要确定一定不会出现有异常抛出的情况,这种写法建议不要用或者少用。
testresult = try! myDog4.printDogMessage(dog: myDog4)   //"dog的信息为小白狗Optional(18)"
if  (testresult != nil){
    print("完成设置!")
} else {
    print("条件不符,无法设置")

}
//输出"完成设置!\n"

2. try? 的使用

try?:与上面的写法类似,不同的地方在于,当有错误或者异常时不会抛出异常,而是给结果反回nil,这种写法适用于不需要处理异常的情况,成功就返回结果,失败返回nil,忽略异常信息。

let myDog3 = Dog(name: "小白",age: 18)
//try? ...与上面的写法类似,不同的地方在于,当有错误或者异常时不会抛出异常,而是给结果反回nil,这种写法适用于不需要处理异常的情况,成功就返回结果,失败返回nil,忽略异常信息。
var testresult = try? myDog3.printDogMessage(dog: myDog3)   //nil
if  (testresult != nil){
    print("完成设置!")
} else {
    print("条件不符,无法设置")

}
//输出"条件不符,无法设置\n"

3. 清理收尾 defer

//在你的代码块就要结束前。如果你使用了 defer。 在其之中的代码就会运行。等于说,给了你最后的机会来进行一些处理。
//注意,如果你有多个defer 语句,他们在执行的顺序会和栈一样,最后一个进,第一个出。
func pk() {
    //defer:结束前运行
    defer {
        print("结束")
    }
    print("开始")

    print("进行")
}

pk()
/*输出: 开始 进行 结束 */

参考自http://www.cnblogs.com/LL–Blog/p/5701457.html

相关文章

Swift 正式开源!Swift 团队很高兴宣布 Swift 开始开源新篇章。自从苹果发布 Swfit 编程语言,就成为了...
快,快,快!动动您的小手,分享给更多朋友! 苹果去年推出了全新的编程语言Swift,试图让iOS开发更简单...
开发者(KaiFaX) 面向开发者、程序员的专业平台! 和今年年初承诺的一样,苹果贴出了Swift语言的源码,...
本文由@Chun发表于Chun Tips :http://chun.tips/blog/2014/12/11/shi-yong-swift-gou-jian-zi-ding-yi...
本文由CocoaChina译者leon(社区ID)翻译 原文:THE RIGHT WAY TO WRITE A SINGLETON 在之前的帖子里聊过...
本文由CocoaChina译者leon(社区ID)翻译 原文:THE RIGHT WAY TO WRITE A SINGLETON 在之前的帖子里聊过...