Swift4 内存管理, 可选链, KeyPath
创建: 2018/03/09
完成: 2018/03/09
参照型数据与ARC | |
ARC |
● Swift里, 只有类实例与闭包实例是参照型 ● 生成时参照值为1, 被代入等每次+1, 减少每次-1 ● 为0运行deinit并自动释放 ● 判定实例是否相同 ===/!== ===运算符: 判定是否指向同一个内存位置(类实例, 闭包实例) !==: ===的否定 |
ARC内存管理 | 用ARC进行内存管理就是ARC内存管理 |
强参照循环 | |
实例无法释放的情况 |
参照循环, 即多个属性互相参照 解决方案就是下面两条: 弱参照, 非所有参照 |
弱参照 |
● 参照时被参照物的参照计数不会增加, 加 weak 必须是var, 因为被参照物被释放时值自动改为nil weak var sample: SampleClass 类实例必须至少有一个强参照, 不然ARC=0, 直接释放 ● 零化, 参照物被释放时值自动改为nil ● 用法: 类内部的类实例属性用weak, 防止循环参照 |
非所有参照(unowned reference) |
● 参照时被参照物的参照计数不会增加, 加 unowned ● 和weak一样, 但是不会零化 ● 用法: 参照量不会变nil得情况下用unowned代替weak 类似于T!和T? ● 速度不重要时, 都用weak |
Xcode去表示参照关系 |
运行项目后, [Debug Memory Graph]按钮 箭头: 被参照物 <-- 参照物 |
可选链 | |
可选链 |
a?.b?.c? // a, b, c都非nil, 返回a.b.c // 任意一个为nil, 返回nil
|
可选链呼出方法 |
前面有nil时方法不执行, 方法的参数是方法也不执行 a?.b?.c?.getSampleData(data: createData(with: 1)) // getSampleData(data:)和createData(with:)都不执行
|
可选链的型 |
可选类型T? a?.b?.c?.name // String? 不用可选链时为T的, 用可选链为T?
|
不返回值的方法的情况 |
不返回值的方法 // 三个返回的型相同 func sample1(...) {...} // 省略返回的型 func sample2(...) -> () {...} // 返回型 () func sample3(...) -> Void {...} // 返回型Void ● 可选链下不返回值的方法的返回型 Void? 作为条件 if a?.b?.c?.method(...) != nil {... } // 相当于 if let _ = a?.b?.c?.method(...) {...}
|
对可选链代入 |
● 左侧可选链取值失败则不代入, 右侧式子不会执行 ● 左侧可选链取值成功则可以代入 ● 除了代入, 复合代入也一样 +=, -=, *=, /=, ... |
key path | |
key path |
可选链那样的参照回路 \型名.路径 // \和型名间可以有空格, 路径可以是可选链或其他属性路径 例 let keyPath1 = \OptionalChainTestClass.complexData?.data ● 路径内不能带有方法名 ● KeyPath的型 KeyPath<起点型, 获取的型> 例 struct Sample { var a:Int } \Sample.a // 型: KeyPath<Sample, Int>
|
用key path进行值的操作 |
● 获取值 实例[keyPath: KeyPath实例] 例 let keyPath1 = \OptionalChainTestClass.complexData?.data print(type(of: keyPath1)) // KeyPath<OptionalChainTestClass, Optional<Int>> print(optionalChainTest[keyPath: keyPath1] ?? "nil") // nil ● 代入 实例[keyPath: KeyPath实例] = 新值
|