iOS中循环引用的解除

一:为什么造成了循环引用??????????????????????????

 

首先    

对于网络工具类  finishedBlock里面 的一个属性是 copy的

那么 NetworkTools 会对网络工具 finishedBlock进行一个强引用

 

左边的控制器viewController里面 

 viewController 对 NetworkTools对象 tools进行强引用 

 

在右边有一个 self.finishedBlock = finished 的赋值

 

在左边的self.view     然后呢      self.finishedBlock = finished  这个对self.view

进行一个强引用    

 

造成了一个闭环  finishedBlock(引用)----self.view()--(self就是那个控制器器 对NetworkTools对象 tools强引用)----tools(引用了)finshedBlock

 

产生了一个闭环  造成了一个封闭的强引用 

 

 

--------结果是谁释放不了

 

 

 

 

二:如何去打断循环引用?????????????????????????

 

 方式1:--打断引用链条         方式2:--使用__weak  

 

方式1: 可以在左边的控制器viewcontroller里面去做一个动作

把那个 self.tools改成一个

NetworkTools * tools  让tools成为一个局部的变量    懂?????

他自然在走出了作用域就会自动释放了    打破了上面的环节   没有了self.view

那个控制器的对他的强引用

这个就是破坏引用链条的原理

 

 

 

方式2: 在

 

 

在左边添加了

  // 方式2

    __weak typeof(self) weakSelf = self;

    

    [self.tools lodaData:^(NSString *html) {

        NSLog(@"%@ %@",html,weakSelf.view);

    }];

添加了这样的东西的话  我们就可以的接触循环引用的

 这个引用链条也会被破坏掉    破坏是在那个   finishedBlock 对self.view的那个环节

 

 

 

总体思路的是:打破循环引用环节的任何一环就行

 

 

方法3: 使用__unsafe_unretained typeof(self) weakSelf = self;

//方法3

    __unsafe_unretained typeof(self)  weakSelf= self;

    [self.tools lodaData:^(NSString *html) {

        NSLog(@"%@ %@",html,weakSelf.view);

    }];

 

 

 

 

 

三:对__unsafe_unretained和 __weak的深度挖掘??????????????

 

我们在网络工具类里面去的做一个耗时操作去模仿网络请求延时操作

 

 __weak是iOS5.0的 

 

 

这个时候  weakSelf.view打印的是null  

如果异步操作没有完成的话,他就会释放控制器   __weak本身是弱引用

当异步操作执行完毕了的话 ,此时进行回到的时候  self已经被释放了 无法再去访问属性   也无法调用方法  所以打印的是null

 

( 所以在点击返回的快慢不同  打印结果不同)

 

 

 

用__unsafe_unretained的时候   __unsafe_unretained是iOS4.0推出的

 

 

 

 

程序就崩溃了     这个MRC的错误     坏内存访问  野指针错误

__weak相当于 weak 不会做强引用      但是如果对象被释放,执行地址会指向nil

 

MRC下面属性的持有都是assign 不会做强引用  但是如果对象被释放

          内存地址还不变  此时再去调用 就会出现野指针的访问

 

所以在开发中一般去推荐__weak    __unsafe_unretained相对于不安全

 

 

还有一种流传出来的代码

(stringSelf强引用 对weakSelf进行强引用 本意 希望在执行完代码了后 继续执行回调)

 

但是如果的话__unsafe_unretained 换成这个  他还是会崩溃的

 

 

总体的区别:

__weak  写法的话  self 已经被释放   只为nil

__unsafe_unretained的话  self已经被释放的话  就会出现野指针访问

 

内部可以使用 strongSelf    但是没有深恶么卵用  

 

posted @ 2016-07-08 11:21  Ninesday  阅读(469)  评论(0编辑  收藏  举报