Swift学习之路-03

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)

访问失败,就是野指针

弱引用和强引用

9ABE0801AD055D96BEF933EDD25B1BE5

个人认为是nil
正确答案是hello

-------------本文结束感谢您的阅读-------------