Swift学习48:ARC
ARC
swift 使用
自动引用计数(ARC)
来跟踪并管理应用使用的内存
。引用计数
只应用在类
的实例。结构体和枚举
都是值类型
,并非引用类型,不是以引用的方式来存储和传递
的
ARC 如何工作
每次创建一个类的实例,
ARC
就会分配一个内存块,用来存储这个实例的相关信息。这个内存块保存着实例的类型,以及这个实例相关的属性的值当实例不再被使用时,ARC 是否这个实例使用的内存,使这块内存可做它用。保证了实例不再被使用时,不会占用内存空间
但是,如果
ARC
释放了仍在使用的实例,那么你就不能再访问这个实例的苏醒或者调用它的方法。如果你仍然视图访问这个实例,应用极有可能会崩溃为了保证不会发生上述的情况,
ARC
跟踪类实例的相关属性、常量及变量的数量。只要有一个有效的引用,ARC
都不会释放这个实例为了让这个变成现实,只要你将一个类的实例赋值给一个属性或常量或变量,这个属性、常量、变量就是这个实例的
强引用(strong reference)
。之所以称之为强引用
,是因为它持有这实例,并且只要这个强引用还存在,就不能销毁实例
循环引用
在两个类实例彼此保持对方的强应用,使得每个实例都使对方保持有效时会发生这种情况。我们称之为强引用环
通过用
弱引用或者无主引用
来取代强引用
,我们可以解决强引用环问题
解决循环引用
弱引用和无主引用
允许引用环中的一个实例引用另外一个实例,但不是强引用
。因此实例可以互相引用但是不会产生强引用弱引用不会增加实例的引用计数
,因此不会阻止ARC销毁被引用的实例。这种特性使得引用不会编程强引用环。声明属性或者变量的时候,关键字weak
表明引用为弱引用。弱引用只能声明为变量类型
,因为运行时它的值可能会变。弱引用绝对不能声明为常量因为弱引用可以没有值,所以声明弱引用的时候
必须是可选类型
的。在swift语言中,推荐使用可选类型作为可能没有值的引用类型
1 | var person: Person? |
对于生命周期中引用会变nil的实例,使用弱引用;对于初始化时赋值之后引用再也不会赋值为nil的实例,使用无主引用
和弱引用相似,
无主引用
也不强持有实例。但是和弱引用不同的是,无主引用默认始终有值
。因此,无主引用只能定义为非可选类型。在属性、变量前添加unowned
关键字,可以声明一个无主引用因为是
可选类型
,因此当使用无主引用时,不需要展开,可直接访问。不过非可选类型变量不能赋值为nil
,因此当实例被销毁的时候,ARC无法将引用赋值为nil
当实例被销毁后,试图访问该实例的无主引用会触发运行时错误。使用无主引用时请确保引用始终指向一个未销毁的实例
1 | class City { |
闭包引用循环
将一个闭包赋值给类实例的某个属性,并且这个闭包使用了实例,这样也会产生强引用环。这个闭包可能反问了实例的某个属性,如果 self.someProperty
,或者调用了实例的某个方法 self.someMethod
。这两种情况都导致了闭包使用 self
,从而产生了循环引用
解决:
定义占有列表-占有列表中的每个元素都是由
weak
或者unowend
关键字和实例的引用(如self
或someInstance
)组成。每一对都在括号中,通过逗号分开当闭包和占有的实例总是互相引用时并且总是同时销毁时,将闭包内的占有定义为无主引用
相反的,当占有引用有时可能会是
nil
时,将闭包内的占有定义为 弱引用
1 | lazy var someClosure = { |
- Post title:Swift学习48:ARC
- Post author:张建
- Create time:2023-03-13 17:44:18
- Post link:https://redefine.ohevan.com/2023/03/13/Swift课程/Swift学习48:ARC/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.