15 可选链和异常处理

1. 可选链

1.1 可选链的概念

  • 它的可选性体现于请求或调用的目标当前可能为空(nil)
    • 如果可选的目标有值,那么调用就会成功;
    • 如果选择的目标为空(nil),则这种调用将返回空(nil)
  • 多次调用被链接在一起形成一个链,如果任何一个节点为空(nil)将导致整个链失效。
  • 可选链的使用
    • 在可选类型后面放一个问号,可以定义一个可选链。
    • 这一点很像在可选值后面放一个叹号来强制拆得其封包内的值
      • 它们的主要的区别在于当可选值为空时可选链即刻失败
      • 然而一般的强制解析将会引发运行时错误。
    • 因为可选链的结果可能为nil,可能有值.因此它的返回值是一个可选类型.
      • 可以通过判断返回是否有值来判断是否调用成功
      • 有值,说明调用成功
      • 为nil,说明调用失败

1.2 示例

  • 从可选链中取值
    • 示例描述: 人(Person)有一个狗(Dog),狗(Dog)有一个玩具(Toy),玩具有价格(price)
// 1.定义类
class Person {
    var name : String
    var dog : Dog?

    init(name : String) {
        self.name = name
    }
}

class Dog {
    var color : UIColor
    var toy : Toy?

    init(color : UIColor) {
        self.color = color
    }

    func runing() {
        print("跑起来")
    }
}

class Toy {
    var price : Double = 0.0
}

// 2.创建对象,并且设置对象之间的关系
// 2.1.创建对象
let person = Person(name: "小明")
let dog = Dog(color: UIColor.yellowColor())
let toy = Toy()
toy.price = 100.0

// 2.2.设置对象之间的关系
person.dog = dog
dog.toy = toy
  • 需求:获取小明的大黄宠物的玩具价格
    • 取出的值为可选类型,因为可选链中有一个可选类型为nil,则返回nil
    • 因此结果可能有值,可能为nil.因此是一个可选类型
let price = person.dog?.toy?.price
print(price) // Optional(100.0)\n
  • 需求:给小明的大黄一个新的玩具
    • 相当于给可选类型赋值
person.dog?.toy = Toy()
  • 需求:让小明的狗跑起来
    • 如果可选类型有值,则会执行该方法
    • 如果可选类型为nil,则该方法不会执行
person.dog?.runing()

2. 异常处理

2.1 异常的介绍

  • 只要我们在编程,就一定要面对错误处理的问题。
  • Swift在设计的时候就尽可能让我们明确感知错误,明确处理错误
    • 比如:只有使用Optional才能处理空值;
  • 如何描述一个错误?
    • 在Swift里,任何一个遵从ErrorType protocol的类型,都可以用于描述错误。
    • ErrorType是一个空的protocol,它唯一的功能,就是告诉Swift编译器,某个类型用来表示一个错误。
    • 通常,我们使用一个enum来定义各种错误的可能性

2.2 异常的示例

  • 假如我们想要读取一个文件中的内容,按照OC的逻辑我们可以这样来模拟
    • 当我们调用方法获取结果为nil时,你并不能确定到底出现了什么错误得到了nil
func readFileContent(filePath : String) -> String? {
    // 1.filePath为""
    if filePath == "" {
        return nil
    }

    // 2.filepath有值,但是没有对应的文件
    if filePath != "/User/Desktop/123.plist" {
        return nil
    }

    // 3.取出其中的内容
    return "123"
}

readFileContent("abc")
  • 使用异常对上述方法进行改进
// 1.定义异常
enum FileReadError : ErrorType {
    case FileISNull
    case FileNotFound
}

// 2.改进方法,让方法抛出异常
func readFileContent(filePath : String) throws -> String {
    // 1.filePath为""
    if filePath == "" {

        throw FileReadError.FileISNull
    }

    // 2.filepath有值,但是没有对应的文件
    if filePath != "/User/Desktop/123.plist" {

        throw FileReadError.FileISNull
    }

    // 3.取出其中的内容
    return "123"
}
  • 处理异常有三种方式
// 3.异常的处理三种方式
// 3.1.try方式,需要手动处理异常
do {
    let result = try readFileContent("abc")
} catch {
    print(error)
}

// 3.2.try?方式,不处理异常,如果出现了异常,则返回一个nil.没有异常,则返回对应的值
// 最终返回结果为一个可选类型
let result = try? readFileContent("abc")

// 3.3.try!方法,告诉系统该方法没有异常.
// 注意:如果出现了异常,则程序会崩溃
try! readFileContent("abc")

你可能感兴趣的:(15 可选链和异常处理)