加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

swift - 内存管理

发布时间:2020-12-14 02:34:21 所属栏目:百科 来源:网络整理
导读:值类型与引用类型 值类型的生命周期仅取决于它的作用域。因此对于值类型不需要考虑内存管理的问题 引用类型(类、函数、closure)的内存管理: - 大多数由ARC完成 - 没有garbage collerctor 下方中关于内存管理的讨论仅适用于引用类型 举例1 --------- -----

值类型与引用类型

值类型的生命周期仅取决于它的作用域。因此对于值类型不需要考虑内存管理的问题

引用类型(类、函数、closure)的内存管理:
- 大多数由ARC完成
- 没有garbage collerctor

下方中关于内存管理的讨论仅适用于引用类型

举例1

--------- ---------       ---------
|object1|       |object3|       |object4|
--------- ---------       ---------
 | | .
 |强 |强 .弱
 |引 |引 .引
 |用 |用 .用
 | | .
 V V V -----------------------------------------
| object2(RC = 2) | -----------------------------------------

RC是对对象强引用的计数
当object1或者object3不存在时,RC会自动减少
当RC = 0时,object2会自动释放
object4是否存在对RC没有影响,但当object2不存在时,object4对object2的引用自动变为nil

举例2

---------  强引用   ---------  强引用   ---------
|object1| --------> |object2| --------> |object3|
---------           ---------           ---------
                        RC=1                RC=1

当object1不存在时,object2和object3都会被释放掉

举例3

RC=2                RC=1
---------  强引用   ---------  强引用   ---------
|object1| --------> |object2| --------> |object3|
---------           ---------           ---------
                        ^                   |
                        |-------------------|
                            强返向引用

反向引用通常是由于回调函数的使用
当object1不存在时,剩下object2和object3互相引用
它们的空间无法使用(不可达)也无法释放(RC=1),于是造成了内存泄漏

RC=2                RC=1
---------  强引用   ---------
|object2| --------> |object3|
---------           ---------
    ^                   |
    |-------------------|
        强返向引用

因此反向引用必须是weak

举例3

--------- |object1| ---------
 |
 |
 V -----------------------------------------------------
|object2 | -----------------------------------------------------
|var lastName = "Spook"                             |
|lazy var greet : ()->() = {                        |
|   print("Hello (self.lastName)"                  |
|} | -----------------------------------------------------

这段代码的问题是自引用
对于closure这样的引用类型,赋值相当于设置引用
也就是说,object2的greet : ()->()指向{print("Hello (self.lastName)"}
而closure中的self.lastname又指向了object2中的lastName

--------- |object1| ---------
 |
 |
 V -----------------------------------------------------
|object2(RC=2) | -----------------------------------------------------
|var lastName = "Spook"                             | <--
|lazy var greet : ()->()                            |   |
----------------------------------------------------- |
 | |
 | -------------------------------------
 V | -----------------------------------------------------
|{                                                  |
|   print("Hello (self.lastName)"                  |
|} | -----------------------------------------------------

解决方案:
使用强引用变为unknown引用

lazy var greet : ()->() =
{ [unknown self] in
    print("Hello (self.lastName)"
|}
Capture List

上文中的[unknown self]就是Capture List 如果把self定义为weak,那么必须把self当作是optional的,使用类型let if的语句对使用if 如果把self定义为unknown,那么self不会成为强引用,且能保证self不为空

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读