error创建 swift
2017-09-18 20:24:00 weixin_34049948 阅读数 53

在Objc中,经常使用的NSError是一个类,使用其自带的类方法可以很方便地构造出一个NSError对象来。
即便是在Swift中使用NSError,也可以使用初始化方法,快速得到一个代表错误的对象。

NSError(domain: "", code: 0, userInfo: nil)

然而在Swift中,去掉NS以后的Error不再是一个类,它是个协议。

2419179-b0755017852a4ed5.png
Error定义.png

那好,既然想要一个Error对象,而系统又没有现成可直接使用的类来创建错误对象,那就自己定义一个:

2419179-a865ee71ce47bf58.png
自定义一个Error.png

然后会发现其自带一个属性:localizedDescription,这个属性是对于一个Error来说最重要的属性之一,现在取出来看看是怎样的:

2419179-03665c7bb2bfdfd8.png
localizedDescription.png
2419179-33977a2b6525195f.png
DESC

它有一个默认值:"操作未完成"。既然是自定义的Error,我们希望localizedDescription的值可以根据不同情况改变,当尝试进行error.localizedDescription = "xxx"这样的赋值操作时,会发现不允许,它是一个只读属性。

那就尝试一下在自定义的Error中"重写"这个属性吧,并让构造方法接受传参:

2419179-53f41c4a99b9e73d.png

这里成功地把localizedDescription改掉了,但是在以前用这个方法是改不了的[懵]~
如果上一步没有把localizedDescription改掉,那么可以尝试去实现Error协议的子协议LocalizedError

2419179-83a8b16c6eb350bb.png
LocalizedError.png

LocalizedError协议定义了4个属性,其中的errorDescription对应的就是localizedDescription的取值,比如可以这样写:

2419179-6b95f8c1a279ca30.png
errorDescription.png

总结一下

  1. Error是个协议,要用它,得自己写个类遵循协议。
  2. localizedDescription属性可以在类里实现以达到赋值的目的。
  3. 如果实现localizedDescription属性,发现实际在取值时,并没有正确取到值,那么可以让自己的类去实现LocalizedError协议,并实现errorDescription属性。
2017-01-22 18:52:03 comebaby29 阅读数 88

/*

  Swift error represented by types that conform to Error protocol

 

 */


//example


enum VendingMachineErr: Error {

    case invalidSelection

    case insufficientMoney(coinsNeeded:Int)

    case outOfStack

}


//throw VendingMachineErr.insufficientMoney(coinsNeeded: 5)



/*

  functions with throws keyword throwing error

    next time you call this function you have to put try keyword

 */


struct Snack{

    var itemCount:Int

    var itemPrice:Int

}


class VendingMachine{

    var itemList=["WangLaoJi":Snack(itemCount:10,itemPrice:3),

                  "JiaDuoBao":Snack(itemCount:10,itemPrice:2),

                  "MiMi":Snack(itemCount:10,itemPrice:1)]

    var coins=0

    /* 

    var a:Snack{

        get {

            return itemList["MiMi"]! // remember dictionary returns optional

        }

    }*/

    func vend(itemName:String) throws {

        guard let item = itemList[itemName] else{

            throw VendingMachineErr.invalidSelection

        }

        guard item.itemCount > 0 else{

            throw VendingMachineErr.outOfStack

        }

        guard item.itemPrice <= coins else{

            let gap = item.itemPrice - coins

            throw VendingMachineErr.insufficientMoney(coinsNeeded: gap)

        }

        coins -= item.itemPrice

        //item.itemCount -= 1 //it's value type, so doesn't count

        itemList[itemName]?.itemCount -= 1// dictional returns optional

        

        print("dispensing \(itemName)")

    }

}


var machine1 = VendingMachine()

machine1.coins = 1

machine1.itemList["MiMi"]?.itemCount

//try machine1.vend(itemName: "MiMi")

machine1.itemList["MiMi"]?.itemCount

do {

    try machine1.vend(itemName: "WangLaoJi")

}catch VendingMachineErr.invalidSelection{

    print("Don't have the item you looking for")

}catch VendingMachineErr.insufficientMoney(var gap){

    // var gap      just like switch case in enum

    print("insert \(gap) coins")

}


/*

    try? try!

 */


func test() throws -> String?{

    return "something"

}


func someTest() -> String?{

    if let a = try? test() {

        return a

    }else if let b = try! test(){

        return b

    }

    return nil

}


/*

  defer statements ensure excution  until current scope exited

 */

/*

func processFile(filename:String) throws {

    if exists(filename) {

        let file = open(filename)

        defer{

            close(file)

        }

        while let line = try file.readline(){

            //actions

        }

        

    }

}

 

 */

2016-05-31 15:03:00 iteye_14589 阅读数 12

转载:http://www.cocoachina.com/swift/20150619/12186.html

在 iOS 开发当中,我们会面对很多异常处理。在 Cocoa Touch 中我们使用 NSError 来进行异常处理。在新的 Swift 2.0 中,我们可以使用新的 ErrorType protocol。

在 Swift 中, enum 是最好的方法建立属于你自己的异常类型,你只要在你的 enum 中确认新的 ErrorType。

1
2
3
4
enumMyError:ErrorType{
caseNotExist
caseOutOfRange
}

如何抛出异常

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

1
2
3
funcmyMethodRetrunString()throws->String
//Noreturn,wecanjustaddthrowsintheend
funcmyMethodRetrunNothing()throws

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

1
2
3
4
5
6
7
8
9
funcmyMethod()throws
//...
//itemisanoptionalvalue
guardletitem=itemelse{
//needthrowstheerrorout
throwMyError.NotExist
}
//dowithitem
}

上面这段代码使用了 guard 来进行unwrap optional value。这是 Swift 2.0 提供的一个新的方法。

Guard

在 Haskell, Erlang 等语言中早已存在 guard,在这里有更多关于它的介绍

guard 翻译过来可以理解为守护,守卫。

在 Swift 中,guard 有点像 if 但是他们有两个非常重要的区别

  • guard 必须强制有 else 语句

  • 只有在 guard 审查的条件成立,guard 之后的代码才会运行 (像守卫一样,条件不符就不让过去)。

guard 中的 else 只能执行转换语句,像 return, break, continue 或者 throws 当然你也可以在这里返后一个函数或者方法。

值得注意的是,guard的使用会提高你代码的可读性,但是也代表你的代码的执行会有非常明确的顺序性,这一点需要开发者们留心处理。

虽然我们在异常处理中提到了 guard 但是不代表它只能在异常处理中使用。它具有广泛的适用性,或许过阵子我会专门为 guard的使用写篇文章。

如何获取并处理异常?

上文讲述了如何建造抛出异常,获取和处理异常就变得很简单了。使用 do-catch 机制。

1
2
3
4
5
do{
tryfunctionWillThrowError()
}catch{
//dealwitherror
}

do-catch 机制简单易懂。很多编程语言也使用类似的机制进行异常处理,但是在 Swift 中有一个比较重要的特性。

catch 和 switch 一样具有Pattern Matching的能力。所以,使用 catch 你可以对异常的解析进行更为高级的处理

1
2
3
4
5
6
7
do{
tryfunctionWillThrowError()
}catchMyError.NotExist{
//dealwithnotexist
}catchMyError.OutOfRange{
//dealwithnotexist
}

这里值得提一下在 Swift 2.0中一个跟异常处理没有关系的改进

Swift 2.0 中没有了 do-while循环,取而代之的是 repeat-while。苹果说这个改动是为了增强代码的可读性。但是我更觉得是为了让我们更舒服的使用 do-catch

不处理异常

如果我不想处理异常怎么办,或者说,我非常确定某个方法或者函数虽然声明会抛出异常,但是我自己知道我在使用时候是绝对不会抛出任何异常的。这种情况下 我们可以使用 try!

1
try!functionThrowErrorNil()

当然,如果你使用 try!,而你的方法或者函数抛出了异常,那么你会得到一个运行中异常 (runtime error) 所以我们开发者需要慎用哦。

Defer

文章结束前我们再讨论下 defer

在你的代码块就要结束前。如果你使用了 defer。 在其之中的代码就会运行。等于说,给了你最后的机会来进行一些处理。如果你熟悉 BDD 或者 TDD, 那么你可以参考他们中的 aferAll 机制

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
funcmyFunction()throws{
defer{
//NomatterwhathappenedIneeddosomething
print("Alldone,cleanuphere")
}
guardletitem=itemelse{
//needthrowstheerrorout
throwMyError.NotExist
}
guarditem.count>maxNumberelse{
//needthrowstheerrorout
throwMyError.OutOfRange
}
//dosomethingwithitem
//...
}

注意,如果你有多个defer 语句,他们在执行的顺序会和栈一样,最后一个进,第一个出。

总结

  • 使用 ErrorType 的帮助建立你的异常类型

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

  • 使用 do-catch 机制来获取和处理异常

2019-05-21 10:09:00 weixin_33863087 阅读数 1

响应错误以及从错误中恢复的过程

抛出、捕获、传递、操作可回复错误

表示与抛出错误

Swift 中,错误用遵循 Error 空协议类型的值来表示用于错误处理
枚举构建一组错误状态

enum VendingMachineError: Error {
    case invalidSelection
    case insufficientFunds(coinsNeeded: Int)
    case outOfStock
}
// 抛出错误
throw VendingMachineError.insufficientFunds(coinsNeeded: 5)

处理错误

4 种错误处理的方式

  • 把函数抛出的错误传递给调用此函数的代码
  • do catch 语句处理错误
  • 将错误作为可选类型处理 try?
  • 断言此错误根本不会发生 try!

用 throwing 函数传递错误

一个标有关键字 throws 关键字的函数称为 throwing 函数

  • throws 关键字需要写在返回值箭头(->)的前面
  • 一个 throwing 函数可以在其内部抛出错误,并将错误传递到函数被调用时的作用域内
struct Item {
  var price: Int
  var count: Int
}

class VendingMachine {  
    var inventory = [
        "Candy Bar": Item(price: 12, count: 7),
        "Chips": Item(price: 10, count: 4),
        "Pretzels": Item(price: 7, count: 11)
    ]
    var coinsDeposited = 0
    
    func vend(itemNamed name: String) throws {
        guard let item = inventory[name] else {
            throws VendingMachineError.invalidSelection
        }

        guard item.count > 0 else {
            throw VendingMachineError.outOfStock
        }

        guard item.price <= coinsDeposited else {
            throw VendingMachineError.insufficientFunds(coinsNeeded: item.price - coinsDeposited)
        }
        
        coinsDeposited -= item.price
        
        var newItem = item
        newItem.count -= 1
        inventory[name] = newItem
        
        print("Dispensing \(name)")
    }
}

函数抛出的错误传递给调用函数的代码

let favoriteSnacks = [
    "Alice": "Chips",
    "Bob": "Licorice",
    "Eve": "Pretzels"
]
func buyFavoriteSnack(person: String, vendingMachine: VendingMachine) throws {
    let snackName = favoriteSnacks[person] ?? "Candy Bar"
    try vendingMachine.vend(itemNamed: snackName)
}

用 Do-Catch 处理错误

在 do 子句中的代码抛出错误,这个错误会与 catch 子句做匹配,从而决定哪条子句能处理它

var vendingMachine = VendingMachine()
vendingMachine.coinsDeposited = 8
do {
    try buyFavoriteSnack(person: "Alice", vendingMachine: vendingMachine)
    print("Success! Yum.")
}  catch VendingMachineError.invalidSelection {
    print("Invalid Selection")
} catch VendingMachineError.outOfstock {
    print("Insufficient funds. Please insert an additional \(coinsNeeded) coins")
} catch { // 如果一条 catch 子句没有匹配指定模式,那么这条子句可以匹配任何错误
    print("Unexpected error: \(error).")
}
// 打印 Insufficient funds. Please insert an additional 2 coins

将错误转换成可选值

可以使用 try? 通过将错误转换成一个可选值来处理错误,抛出错误返回 nil

func someThrowingFunction() throws -> Int {  
    // ...
}
let x = try? someThrowingFunction()

let y: Int?
do {
    y = try someThrowingFunction()
} catch {
    y = nil
}

禁用错误传递

断言此 throwing 函数不会抛出错误 try!,如果抛出错误,程序奔溃

let photo = try! loadImage(atPath: "./Resource/John Appleseed.jpg")

指定清理操作

使用 defer 语句在 return 之前执行一系列代码

  • 延迟执行的语句不能包含任何控制转移语句,例如 break、return 或是抛出一个错误
  • 延迟执行操作会按照它们声明的顺序从后往前执行,也就是说第一个声明 defer 语句中的代码最后才执行
func processFile(filename: String) throws {
    if exists(filename) {
        let file = open(fileName)
        defer {
          close(file)
        }
        while let line = try file.readline() {
            // 处理文件
        }
        // close(file) 会在这里被调用,即作用域的最后
    }
}

转载于:https://www.jianshu.com/p/b2e9d3de1a89

2018-02-10 16:19:48 Xoxo_x 阅读数 1512

Swift 4 中 Error 远没有NSError灵活

虽然我们可以打印error.localizedDescription但是依旧没有办法获取描述信息,而且我们似乎只能通过NSError来创建Error
如:

let error = NSError.init(domain: "我爱你 success", code: 0001, userInfo: nil) as Error
print(error)
print(error.localizedDescription)

log信息:

Error Domain=我爱你 success Code=1 "(null)"
The operation couldn’t be completed. (我爱你 success error 1.)

如我们需要使用我爱你 success这个信息作为alert呈现给用户,那么我们可以这样做:

let error1 = error as NSError
print(error1.domain)

而且error 转换到 NSError是永远成功的
log:
我爱你 success

完整代码:

let error = NSError.init(domain: "我爱你 success", code: 0001, userInfo: nil) as Error
print(error)
let error1 = error as NSError
print(error1.domain)

Swift Compiler Error

阅读数 4

swift创建函数

阅读数 577

Swift创建UITableview

阅读数 173

swift创建代理

阅读数 263

没有更多推荐了,返回首页