Swift(十六、自动引用计数)

Swift(十六、自动引用计数),第1张

概述1、Swift入门学习笔记(第一版),对Swift的基础知识点进行梳理总结。知识点一直在变,只是作为参考,以苹果官方文档为准~ 2、在学习完基本的知识点以后会结合官方文档及相关资料,在此版本的基础上进行添加更改。 十六、自动引用计数 引用计数仅适用于类实例。结构体和枚举类型是值类型,不是引用类型,不是通过引用方式存储和传递 1、自动引用计数的工作机制 与OC大同小异,此处不累述 class Per

1、Swift入门学习笔记(第一版),对Swift的基础知识点进行梳理总结。知识点一直在变,只是作为参考,以苹果官方文档为准~

2、在学习完基本的知识点以后会结合官方文档及相关资料,在此版本的基础上进行添加更改。

十六、自动引用计数

引用计数仅适用于类实例。结构体和枚举类型是值类型,不是引用类型,不是通过引用方式存储和传递

1、自动引用计数的工作机制

与OC大同小异,此处不累述

class Person {    init() {        print("Init")    }    deinit {        print("Deinit")    }}var reference1:Person?var reference2:Person?var reference3:Person?//定义为可选类型是为了可赋nilreference1 = Person()       //输出Initreference2 = reference1     //无输出reference3 = reference1     //无输出//赋值nil,断开强引用reference1 = nil            //无输出reference2 = nil            //无输出reference3 = nil            //输出Deinit
2、循环引用解决方案

与OC大同小异,此处不累述

Swift提供两种解决循环引用的问题:弱引用(weak reference)和无主引用(uNowned reference)
在生命周期内会变为nil的实例使用弱引用。对初始化赋值后不会被赋值为nil的实例使用无主引用

3、弱引用

a、weak关键字表示弱引用,一方强一方弱

b、必须声明为变量,表示其值在运行时可修改

c、必须声明为可选类型,因为弱引用可为nil

class Person {    var pet:Dog?    deinit {        print("Person deinit")    }}class Dog {    weak var owner:Person?    deinit {        print("Dog deinit")    }}//可选类型,一个人可以有狗也可以没狗,一只狗可以有主人也可以是流浪狗//建立引用关系var person:Person? = Person()var pet:Dog?       = Dog()person!.pet        = petpet!.owner         = personperson = nil        //person的引用计数为0,person被释放,pet引用计数变为2pet    = nil        //pet引用计数变为0

Output:

Person deinitDog deinit

注意:在使用垃圾收集的系统里,弱指针有时用来实现简单的缓存机制,因为没有强引用的对象只会在内存压力触发垃圾回收时才被销毁,但在ARC中一旦不被强引用,就会被立刻销毁,因此不适合用来实现缓存

3、无主引用

a、uNowned表示无主引用

b、无主引用永远有值

c、总是被定义为非可选类型

class Person {    var pet:Dog?    deinit {        print("Person deinit")    }}class Dog {    uNowned let owner:Person    init(owner:Person) {        self.owner = owner    }    deinit {        print("Dog deinit")    }}//可选类型,一个人可以有狗也可以没狗,但是狗必须要有主人var person:Person?person = Person()person!.pet = Dog(owner: person!)//person引用计数为1,dog引用计数也为1只有person引用它person = nil//person为nil,那么没有指向Person实例的强引用,实例被销毁。之后,指向Dog实例的强引用也没了,该实例随之被销毁

Output:

Person deinitDog deinit
4、无主引用及隐式解析可选属性

前面阐述了两个实例均可以为nil的情况使用弱引用,以及其中一方为nil使用无主引用。
接下来阐述两方都必须有值,均不能为nil的情况

解决方法:一个类使用无主属性,另一个类使用隐式解析可选属性
实际上 *** 作跟上面的一样,就是改成,表示不能为nil即可

class Person {    var pet:Dog!    init(petname:String) {        self.pet = Dog(name: petname,owner: self)        print("Person init")    }    deinit {        print("Person deinit")    }}class Dog {    let name:String    uNowned let owner:Person    init(name:String,owner:Person) {        self.name = name        self.owner = owner        print("Dog init")    }    deinit {        print("Dog deinit")    }}var person = Person(petname: "Lucky")//person.pet可以被访问,不用!展开print(person.pet.name)

Output:

Dog initPerson initLucky
5、闭包引起的循环引用

如果闭包定义在类内部,而类又引用了实例的属性或者方法(捕获),产生循环引用

解决方案:闭包捕获列表

class Person {    var name:String    lazy var printname:VoID -> VoID = {       print(self.name)    }    init(name:String) {        self.name = name    }    deinit {        print("Deinit")    }}//lazy延迟加载,只有当类实例构造完成之后才得到,不加无法使用self
var p:Person? = Person(name: "Zane")p = nil

Output:

Deinit

由打印结果可知,p实例销毁了,因为闭包只有在使用的时候才会初始化,因此这里没有循环引用

接下来使用闭包

var p1:Person? = Person(name: "Zane")p1!.printname()p1 = nil

Output:

Zane

打印结果并没有Deinit,循环引用,实例未释放

解决方法:定义捕获列表,声明每个捕获的引用为弱引用或者无主引用

a、包含参数列表和返回类型,把捕获列表放前面,以及一些初始化的变量例如delegate等,逗号隔开

lazy var test:(Int,String) -> String = {    [uNowned self,weak delegate = self.delegate!](index:Int,string:String)->String in    //闭包 *** 作}

b、无指明参数类型或者返回值,即使有也可以不写,编译器自己推断

lazy var printname:VoID -> VoID = {    [uNowned self] in print(self.name) }

这里修饰符weak还是uNowned前文已讲

总结

以上是内存溢出为你收集整理的Swift(十六、自动引用计数)全部内容,希望文章能够帮你解决Swift(十六、自动引用计数)所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1082814.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-27
下一篇2022-05-27

发表评论

登录后才能评论

评论列表(0条)

    保存