Swift学习之路-03
[toc]
swift
循环引用的产生
闭包对self引用 self对闭包引用
接触循环引用 需要打断链条
方法1:OC 的方式
细节1 var,weak 只能修饰 var 不能修饰 let
'weak' must be a mutable variable, because it may change at runtime
weak 可能会被在运行时被修改 ->指向的对象一旦被释放 会被自动设置为 nil
细节2
解包有两种方式的解包
? 可选解包 — 如果 self 已经被释放,不会向对象发送 getter 的消息,更加安全
! 强行解包 — 如果 self 已经被释放,强行解包会导致崩溃
weakSelf?.view - 只是单纯的发送消息,没有计算
强行解包,应为需要计算,可选项不能直接参与到计算!
方法2 - Swift 的推荐方法
[weak self] 表示{}的所有 self 都是弱引用 ,需要注意解包
loadData {
[weak self] in
print(self?.view as Any)
}
方法3 - Swift 的另一个用法,知道就好
[unowned self] 表示 {} 中的所有 self 都是 assign 的 不会强引用,但是 ,如果对象释放,指针地址不会变化
如果对象被释放,继续调用,就会出现野指针的问题,奔溃信息如下
loadData {
[unowned self] in
print(self.view)
}
奔溃信息
Thread 1: Fatal error: Unexpectedly found nil
OC解决循环引用的两种方法
解除循环引用1: __weak
// __weak typeof(self) weakSelf = self;
// [self loadData:^{
// NSLog(@"%@",weakSelf.view);
// }];
解除引用2: __unsafe_unretained
// 高级iOS 如果需要自行管理e内存 可以考虑使用 但是不建议使用
// EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
坏内存访问,野指针
__unsafe_unretained 同样是 assign 的引用(MRC 没有weak)
在 MRC中如果要引用对象都是使用 assign ,不会增加引用计数,但是一旦对象被释放,地址不会改变,继续访问,出现野指针
在ARC weak 本质上是一个u观察者模式,一旦发现对象被释放,会自动将地址设置为nil 更加安全
效率: weak 的效率会略微差一些!
__unsafe_unretained typeof (self) weakSelf = self;
[self loadData:^{
NSLog(@"%@",weakSelf.view);
}];
崩溃信息
EXC_BAD_ACCESS (code=EXC_I386_GPFLT)
访问失败,就是野指针
弱引用和强引用
个人认为是nil
正确答案是hello