swift学习日记(九) 自动引用计数 可选链

最近要开始期末复习了,尽早搞完swift部分,iOS部分要搁置到放假后在家弄了,期末加油!!


一,自动引用计数 ARC


看起来挺高大上的是不?


这部分主要应用在内存管理上,已经是比较高级的语法了,毕竟swift大多数时候是不用程序猿去管理内存的


这一部分大多数都不需要我们亲自操作,不过最好还是了解一下原理比较好


1,强引用

class Person {
    let name: String
    init(name: String) {
        self.name = name
        print("\(name) is being initialized")
    }
    deinit {
        print("\(name) is being deinitialized")
    }
}
var reference1: Person?
var reference2: Person?
var reference3: Person?
reference1 = Person(name: "John Appleseed")
reference2 = reference1
reference3 = reference1
reference1 = nil
reference2 = nil
reference3 = nil

注意,类是引用类型,所以实际上三个变量指向的是同一个实例


除了实例外,swift还有一个强引用的概念,你可以把强引用理解成连接 变量 和 其指向的实例 的一个特殊的数据结构,一个实例所拥有的强引用数量,代表了有多少个变量指向该实例,只有一个实例没有任何强引用,其才会调用析构函数。


所以在上述代码中,构造函数和析构函数都只调用了一次


2,弱引用和无主引用


有强引用就有弱引用嘛


强引用会造成一个问题


如果两个类互相有对方类型的属性,那么两个类在实例化后,将不会被析构,因为类中有另一个类的强引用,每个实例的强引用都不为0

解决这个问题就需要弱引用


弱引用也可以理解成连接实例和变量的一个数据结构,但是不管一个实例有没有弱引用,实例都可以进行析构

比如这样

class Person {
    let name: String
    init(name: String) { self.name = name }
    var apartment: Apartment?
    deinit { println("\(name) is being deinitialized") }
}
class Apartment {
    let number: Int
    init(number: Int) { self.number = number }
    weak var tenant: Person?
    deinit { println("Apartment #\(number) is being deinitialized") }
}

在var前声明weak关键字,即为弱引用,这样就不会造成上面描述的问题,术语叫做 强引用循环


当弱引用指向的实例被析构后,变量将被赋值为nil


注意,在声明弱引用时,最好加上可选类型,因为其是弱引用,很可能会被置为nil


class Person {
    let name: String
    init(name: String) {
        self.name = name
        print("\(name) is being initialized")
    }
    deinit {
        print("\(name) is being deinitialized")
    }
}
var reference1: Person?
weak var reference2: Person?
weak var reference3: Person?
reference1 = Person(name: "John Appleseed")
reference2 = reference1
reference3 = reference1
reference1 = nil
print(reference2?.name)



无主引用是比弱引用更弱的一种


无主引用和弱引用最大的不同在于,无主引用不能是可选类型(弱引用必须是可选类型)


在弱引用中,如果你试图访问一个未确认的nil变量,会返回一个nil


在无主引用中,因为不是可选类型,在析构后再试图访问会直接报错,所以必须保证声明了无主引用的属性或变量必须会有一个值


3,隐式拆箱可选类型

还有一种情况更加严重,会在初始化的时候就出错

class Country {
    let name: String
    let capitalCity: City!
    init(name: String, capitalName: String) {
        self.name = name
        self.capitalCity = City(name: capitalName, country: self)
    }
}
class City {
    let name: String
    unowned let country: Country
    init(name: String, country: Country) {
        self.name = name
        self.country = country
    }
}

如果两个类的构造函数互相有对方类型,这可能会造成循环构造


所以就需要隐式拆箱可选类型,其实语法上就是可选类型

如代码,Country类在构造的时候要初始化一个City类,但是传给Country的参数可以是self,也就是把自己给传过去了,这样就可以避免循环构造


后来还有一些比较难的,不过我看了一会似乎暂时也很难用到,就暂时先搁置了


二,可选链


可选链(Optional Chaining)是一种可以请求和调用属性、方法及子脚本的过程,它的自判断性体现于请求或调用的目标当前可能为空(nil)。如果自判断的目标有值,那么调用就会成功;相反,如果选择的目标为空(nil),则这种调用将返回空(nil)。多次请求或调用可以被链接在一起形成一个链,如果任何一个节点为空(nil)将导致整个链失效。


这段我也不好怎么自己解释,就直接复制了


可选链最大的作用是在一条链上的某个属性为nil时,对其进行访问不会发生运行错误,而是转为弹出一个信息等方式来报告错误


这个应该也是更多在工程上的应用,这里我就只贴个概念


class Person {
    var residence: Residence?
}

class Residence {
    var numberOfRooms = 1
}
let john = Person()
if let roomCount = john.residence?.numberOfRooms {
    println("John's residence has \(roomCount) room(s).")
} else {
    println("Unable to retrieve the number of rooms.")
}
// 打印 "Unable to retrieve the number of rooms.


是不是跟以前可选类型有点像,不同的地方在于if语句中的 ? 表明这是个可选类型

这更多是一种思想,而不是语法


暂时先到这里,前两天又断更了,抱歉

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值