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 但是没有深恶么卵用