内存管理

跟OC一样,Swift也是采取基于引用计数的ARC内存管理方案(针对对空间)

Swift的ARC中有3种引用
强引用:默认情况下,引用都是强引用

弱引用:通过weak定义弱引用
必须是可选类型的var,因为实例销毁后,ARC会自动将弱引用设置为nil
ARC自动给弱应用设置nil时,不会触发属性观察器

无主引用:通过unowned定义无主引用
不会产生强引用,实例销毁后仍然存储着实例的内存地址
试图在实例销毁后访问无主引用,会产生运行时错误(野指针)

weak、unowned的使用限制
weak、unowned只能用在类实例上面

protocol Livable AnyObject{).png

因为只有类实例才能被赋值nil

Autoreleasepool

pub lic func autoreleasepooleResulta ( invoking body () throus• Result) rethrows• Resolt.png

循环引用(Reference Cycle)

weak、unowned 都能解决循环引用的问题,unowned要比weak少一些性能消耗
在生命周期中可能会变为nil的使用weak
初始化赋值也不会变为nil的使用unowned

闭包的循环引用

闭包表达式默认会对用到的外层对象产生额外的强引用(对外层对象进行了retain操作)

下面代码会产生循环引用,导致Person对象无法释放(看不到Person的deinit被调用)

pub lic func autoreleasepooleResulta ( invoking body () throus• Result) rethrows• Resolt.png

没有打印 “deinit”

在闭包表达式的捕获列表声明weak或unowned引用,解决循环引用问题

• class Person.png
class Person.png

闭包的循环引用

如果想在定义闭包属性的同时引用self,这个闭包必须是lazy的(因为在实例初始化完毕之后才能引用self)

class Person.png
class Person.png

左边的闭包fn内部如果用到了实例成员(属性、方法)
编译器会强制要求明确写出self

如果lazy属性是闭包调用的结果,那么不用考虑循环引用的问题 (因为闭包调用后,闭包的生命周期就结束了)

class Person {.png

相当于一个方法去获取值

方法结束后引用关系都结束了

@escaping

非逃逸闭包、逃逸闭包,一般都是当做参数传递参数
非逃逸闭包:闭包调用发生在函数结束前,闭包调用在函数作用域内(很安全,self 释放之前)
逃逸闭包:闭包有可能在函数结束后调用, 闭包调用逃离了函数的作用域, 需要通过@escaping声明

eoort.png
class Person.png

非逃逸闭包

如果有逃逸闭包,闭包没有被调用,所被引用的对象也不会被释放。要等逃逸闭包被调用后释放。如果想让对象释放逃逸闭包,要加weak

func run().png
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容