美文网首页
每天学一点Swift----面向对象上(十)

每天学一点Swift----面向对象上(十)

作者: 冯可乐同学 | 来源:发表于2017-06-01 22:51 被阅读16次

    十二.可选链

    1.对于前面的学习的可选类型:Swift的所有类型默认不能接受nil值,如果程序想让某种数据类型接受nil值,则必须将这种数据类型包装成可选类型。——两种方法:在原有的类型后面加?后缀,要进行强制解析;在原有的类型后加!后缀,由Swift隐式解析。

    2.可选链正是用于处理这里可选类型的属性、方法、下标等的。

    3.为了更好的理解,直接从代码例子入手:

    下面的定义了3个类,这3个类之间存在关联关系,而且程序使用了可选类型类维护它们之间的关联关系:

    class Customer

    {

    var name = "xx顾客"

    var emp : Employee?//注意这里有个问号----强制解析

    init(name : String)

    {

    self.name = name

    }

    }

    class Employee

    {

    var name = "xx职工"

    var title = "销售"

    var comp : Company!//注意这里有个感叹号----隐式解析

    init(name : String, title : String)

    {

    self.name = name;

    self.title = title

    }

    }

    class Company

    {

    var name = "xx公司"

    var addr = ""

    init(name : String, addr : String)

    {

    self.name = name

    self.addr = addr

    }

    }

    3个类的关系是:顾客有一个专门为他负责的职工,职工是属于某个公司的。实例化如下:

    var customer = Customer(name : "习大大")

    var employee = Employee(naem : "马云", title : "销售")

    customer.emp = employee

    var company(name: "阿里巴巴", addr: "杭州")

    employee.comp = company

    //这里就可以获取到:为顾客习大大服务的职工所在的公司名称是:阿里巴巴

    print("为\(customer.name)服务的职工坐在的公司名称是:\(c.emp!.comp.name)")//注意,emp后面有一个感叹号

    4.上面程序中,因为Customer的emp属性类型是Employee?可选类型,因此在程序中使用Customer的emp属性必须使用感叹号进行强制解析。而Employee的comp属性是Company!可选类型,因此程序不需要强制解析,由Swift进行隐式解析即可。

    5.对于上面的程序的来说,因为所有需要关联的地方都没有遗漏,所以上面程序可以正确的运行。但是对于下面的情况则会有不同的结果:

    var c2 = Customer(name : "小明")

    var emp = Employee(name : "小小明", title : "客服")

    print("为\(c2.name)服务的职工所在的公司名称是\(c2.emp!.comp.name)")

    var c3 = Customer(name : "小红")

    print("为\(c3.name)服务的职工所在的公司的名称是:\(c3.emp!.comp.name)")

    ----对于c2来说,Employee实例所关联的Company为nil,因此程序在进行隐式解析可选类型时将会导致运行错误

    ----对于c3来说,c3连Employee的实例都没有关联,因此,程序会对c3.emp!进行强制解析得到nil,也会导致运行时出错

    ----上面两段代码,在编译时可以正常通过,但是运行时就会报错:fatal error

    6.通过上面的会导致出错的例子可以看出,强制解析或隐式解析存在一个缺点:只要访问链中任何一次访问的返回值是nil,程序就会导致错误。

    7.将上面访问链中强制解析的感叹号换成问号后缀,在隐式解析的后面也添加问号后缀,这就是可选链的访问方式。

    8.可选链是一种更加“智能”的方式,可选链会自动判断程序访问的关联实例是否为nil:

    (1)如果关联实例不为nil,可选链会自动解析可选类型所包装的值----就像隐式解析一样。

    (2)如果关联的实例为nil,可选链不会导致运行时错误,可选链将返回一个nil。即,程序的结果为nil。

    将上面5中的输出代码修改如下:

    print("为\(c2.name)服务的职工所在的公司的名称是:\(c2.emp?.comp.name)")//输出为nil

    print("为\(c3.name)服务的职工所在的公司的名称是:\(c3.emp?.comp.name)")//输出为nil

    9.可选链不仅可以用于访问属性,也可以用于调用方法。举个栗子:在刚开始的Customer类增加以下代码:

    //定义一个常量类型的emp数组,用于模拟系统中所有员工

    let employees = {

    Employee(name : "职工1", title : "销售1")

    Employee(name : "职工2", title : "销售2")

    Employee(name : "职工3", title : "销售3")

    Employee(name : "职工4", title : "客服1")

    Employee(name : "职工5", title : "客服2")

    }

    //定义一个方法,该方法可根据员工的名称返回对应的员工信息,返回值为可选类型

    func findEmp(empName : String) -> Employee!----注意,这里有个感叹号

    {

    for emp int employees

    {

    if emp.name == empName

    return emp

    }

    return nil

    }

    10.上面的程序中,调用Customer实例的findEmp方法是,如果进行强制解析或隐式解析该返回值,并用该返回值调用方法时就有可能导致运行时错误。但如果程序使用可选链就可以避免错误,使用可选链的代码如下:

    c3.findEmp("嫦娥")?.info()

    c3.findEmp("KoBe")?.info()

    11.当下标返回值类型为可选类型时,下标的返回值同样有可能为nil,此时可对下标使用可选链。举个栗子:

    var dict = [Int : Customer]()

    dict[1] = Customer(name : "唐僧")

    dict[2] = Customer(name : "悟空")

    dict[3] = Customer(name : "八戒")

    dict[4] = Customer(name : "沙僧")

    dict[1]?.findEmp("白龙马")?.info()----第二个问号那里返回nil

    dict[2]?.findEmp("白龙马")?.info()——第一个问号那里返回nil

    相关文章

      网友评论

          本文标题:每天学一点Swift----面向对象上(十)

          本文链接:https://www.haomeiwen.com/subject/dnkyfxtx.html