微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Swift错误处理

Swift错误处理

参考:

强制退出程序

使用assert,表达式为假,程序强制退出

assert(1>0,"Error")

assert还有一种形式为assertionFailure,程序走到这个函数时,程序会直接终端,并打印中断的信息

assertionFailure("failure")

注意assertassertionFailure都只在开发的过程中起作用,当release程序后,assertassertionFailure自动失效了。

不过有些时候,希望程序在真正执行起来的时候,在某些情况下,遇到一些严重的错误,程序要强制退出,可以使用preconditionfatalError

precondition(1>0,"Error") fatalError("Error")

Error

在一般的处理过程中可以返回nil表示错误,但是只返回nil,不能表示出错的原因。比如连接网络,如果网络连接不上,就返回一个nil,这样做也是可以的,但是此时只是知道网络没连接上而已。至于是服务端出错还是客户端出错,就不得而知了。所以需要一套完善的错误处理机制。

1.自定义错误类型:

  • 遵守Error协议

如下:

enum vendingError: Error{
        case NoSuchItem
        case NotEnoughMoney(Int)
        case OutOfStock
    }

2.抛出错误,使用throws关键字,抛出错误后,整个函数就已经结束了,所以后面就不用return
真正抛出异常使用throw关键字

func vend(itemName itemName: String,money: Int) throws -> Int{

        guard let item = items[itemName] else{
            throw vendingMachine.vendingError.NoSuchItem
        }

        guard money >= item.price else{
            throw vendingMachine.vendingError.NotEnoughMoney(item.price)
        }

        guard item.count > 0 else{
            throw vendingMachine.vendingError.OutOfStock
        }

        return money - item.price
    }
   }

此时,这个函数就有两种退出的方式:

1.正确的return
2.抛出异常

错误处理

对于抛出异常的函数,就不能直接调用了,要处理异常。使用try关键字

try!表示坚信函数不会抛出异常,但是这样写也是有风险的。

try! machine.vend(itemName: "Coca Cola",money: pocketMoney)

try?表示如果抛出异常,返回值为nil。所以对于返回值可以使用解包的形式:

if let leftMoney = try? machine.vend(itemName: "Coca Cola",money: pocketMoney)
{

}else{

}

如果希望更具错误的类型,来做不同的处理。就需要使用docatch关键字,如下:

do{
    pocketMoney = try machine.vend(itemName: "Coca Cola",money: pocketMoney)
    print(pocketMoney,"Yuan left")
}catch{
    print("Error occured during vending")
}

要处理不同类型的异常,形式如下:

do{
    pocketMoney = try machine.vend(itemName: "Coca Cola",money: pocketMoney)
    print(pocketMoney,"Yuan left")
}catch vendingMachine.vendingError.NoSuchItem{
    print("No Such Item")
}catch vendingMachine.vendingError.NotEnoughMoney(let price){
    print("No Enough Money",price,"Yuan needed.")
}catch vendingMachine.vendingError.OutOfStock{
    print("Out of Stock")
}catch{
    print("Error occured during vending.")
}

还有一种形式是:

do{
    pocketMoney = try machine.vend(itemName: "Coca Cola","Yuan left")
}catch let error as vendingMachine.vendingError{

}catch{
    print("Error occured during vending.")
}

defer

在其它语言中,错误处理通常有个finally关键字,不管程序是否抛出异常,finally中的代码都要执行。

swift中引入了defer,它应该写在有可能退出这个函数的语句之前。defer本身的意识是延迟,表示延迟执行。

func vend(itemName itemName: String,money: Int) throws -> Int{

        defer {
            print("Hava a nice day")
        }

        guard let item = items[itemName] else{
            throw vendingMachine.vendingError.NoSuchItem
        }
        ......
    }

如果有多个defer,是按倒序来执行的,如下的方法

func vend(itemName itemName: String,money: Int) throws -> Int{

        defer {
            print("Hava a nice day")
        }

        guard let item = items[itemName] else{
            throw vendingMachine.vendingError.NoSuchItem
        }

        guard money >= item.price else{
            throw vendingMachine.vendingError.NotEnoughMoney(item.price)
        }

        guard item.count > 0 else{
            throw vendingMachine.vendingError.OutOfStock
        }

        defer {
            print("Thank you")
        }

        dispenseItem(itemName: itemName)

        return money - item.price
    }

    private func dispenseItem(itemName: String){
        items[itemName]!.count -= 1
        print("Enjoy your",itemName)
    }

如果调用如下的方法,正常的执行,不会抛出异常:

var pocketMoney = 3
try? machine.vend(itemName: "Coca Cola",money: pocketMoney)

则其输出顺序为:

Enjoy your Coca Cola
Thank you
Hava a nice day

如果调用如下方法,抛出异常:

var pocketMoney = 2
try? machine.vend(itemName: "Coca Cola",money: pocketMoney)

则控制台只会输出

Hava a nice day

这是因为抛出异常结束程序,只会找抛出异常之前的defer语句

原文地址:https://www.jb51.cc/swift/321288.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐