Swift(十六、自动引用计数)
2015-11-10 19:29
453 查看
1、Swift入门学习笔记(第一版),对Swift的基础知识点进行梳理总结。知识点一直在变,只是作为参考,以苹果官方文档为准~
2、在学习完基本的知识点以后会结合官方文档及相关资料,在此版本的基础上进行添加更改。
Swift提供两种解决循环引用的问题:弱引用(weak reference)和无主引用(unowned reference)
在生命周期内会变为
b、必须声明为变量,表示其值在运行时可修改
c、必须声明为可选类型,因为弱引用可为
Output:
注意:在使用垃圾收集的系统里,弱指针有时用来实现简单的缓存机制,因为没有强引用的对象只会在内存压力触发垃圾回收时才被销毁,但在ARC中一旦不被强引用,就会被立刻销毁,因此不适合用来实现缓存
b、无主引用永远有值
c、总是被定义为非可选类型
Output:
接下来阐述两方都必须有值,均不能为
解决方法:一个类使用无主属性,另一个类使用隐式解析可选属性
实际上操作跟上面的一样,就是
Output:
解决方案:闭包捕获列表
Output:
由打印结果可知,p实例销毁了,因为闭包只有在使用的时候才会初始化,因此这里没有循环引用
接下来使用闭包
Output:
打印结果并没有Deinit,循环引用,实例未释放
解决方法:定义捕获列表,声明每个捕获的引用为弱引用或者无主引用
a、包含参数列表和返回类型,把捕获列表放前面,以及一些初始化的变量例如delegate等,逗号隔开
b、无指明参数类型或者返回值,即使有也可以不写,编译器自己推断
这里修饰符weak还是unowned前文已讲
2、在学习完基本的知识点以后会结合官方文档及相关资料,在此版本的基础上进行添加更改。
十六、自动引用计数
引用计数仅适用于类实例。结构体和枚举类型是值类型,不是引用类型,不是通过引用方式存储和传递1、自动引用计数的工作机制
与OC大同小异,此处不累述class Person { init() { print("Init") } deinit { print("Deinit") } } var reference1:Person? var reference2:Person? var reference3:Person? //定义为可选类型是为了可赋nil reference1 = Person() //输出Init reference2 = 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 = pet pet!.owner = person person = nil //person的引用计数为0,person被释放,pet引用计数变为2 pet = nil //pet引用计数变为0
Output:
Person deinit Dog 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 deinit Dog 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 init Person init Lucky
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前文已讲
相关文章推荐
- Apple Swift学习教程
- iOS开发之路--微博“更多”页面
- Swift中实现点击、双击、捏、旋转、拖动、划动、长按手势的类和方法介绍
- Swift编程中的泛型解析
- Swift中定义二维数组的方法及遍历方法示例
- 简单分析Swift语言的一些基本特征
- Swift与C语言指针结合使用实例
- Swift心得笔记之控制流
- 用Swift构建一个简单的iOS邮件应用的方法
- 苹果公司推出的新编程语言Swift简介和入门教程
- iOS开发之路--微博骨架搭建
- IOS开发代码分享之获取启动画面图片的string
- Swift中的指针操作和使用详细介绍
- Swift中使用正则表达式的一些方法
- Swift心得笔记之运算符
- Swift中使用可选类型完美解决占位问题
- Swift学习笔记之构造器重载
- Swift中的Access Control权限控制介绍
- Swift类型创建之自定义一个类型详解