谈谈OC中的循环引用
1.什么时候会发生循环引用
将一个提前准备好的代码块, 在需要执行的时候立即执行, 在不需要立即执行的时候, 用个属性将这个函数传递过来的block记录下来, 产生了强引用, 此时就会发生循环引用
2.怎么解决循环引用
那么怎么解决循环引用, 就是打破任一方的强引用
.
其中使用最多的就是weak, 声明一个弱引用类型的自己, 解除循环引用, 其中weak跟weak类似, 当对象被系统回收时, 它的内存地址会自动指向nil, 对nil进行任何操作不会有反应
但其实在ios4的时候, 也可以使用__unsafe_unretained, 解除强引用, 但是它存在一定的不安全性, 原理和assign类似, 当对象被系统回收时, 它的内存地址不会自动指向nil, 就有可能出现坏内存地址的访问, 也就发生野指针错误
在之前发现了很多解除循环引用的时候, 会先使用weak, 声明自己为弱引用类型, 然后在准备好的代码块中也就是block中, 再对弱引用对象利用strong 做一次强操作 , 仔细验证发现再做强引用操作是冗余的, 并不会产生影响, 可以不用写
3.如何验证是否发生循环引用
.
4.simple demo
#import "ViewController.h"#import "NetworkTools.h"@interface ViewController ()@property (nonatomic, strong) NetworkTools *tools;@end@implementation ViewController- (void)viewDidLoad { [super viewDidLoad]; self.tools = [[NetworkTools alloc] init];/* //解决方式三: __unsafe_unretained 不推荐, 不安全 __unsafe_unretained typeof(self) weakSelf = self; [self.tools loadData:^(NSString *html) { __strong typeof(self) strongSelf = weakSelf; NSLog(@"%@%@",html,strongSelf.view); strongSelf.view.backgroundColor = [UIColor redColor]; }]; */ //解决方式二: __weak __weak typeof(self) weakSelf = self; [self.tools loadData:^(NSString *html) { __strong typeof(self) strongSelf = weakSelf; NSLog(@"%@%@",html,strongSelf.view); strongSelf.view.backgroundColor = [UIColor redColor]; }]; }//解决方式一: - (void) method1{ NetworkTools *tools = [[NetworkTools alloc] init]; [tools loadData:^(NSString *html) { NSLog(@"%@%@",html,self.view); self.view.backgroundColor = [UIColor redColor]; }]; } - (void)dealloc { NSLog(@"VC dealloc"); }@end
#import "NetworkTools.h"@interface NetworkTools ()//用一个属性 来记录 函数传递过来的 block@property (nonatomic, copy) void(^finishedBlock)(NSString *);@end@implementation NetworkTools- (void)loadData:(void (^)(NSString *))finishedCallBack { //开始记录blcok self.finishedBlock = finishedCallBack; dispatch_async(dispatch_get_global_queue(0, 0), ^{ [NSThread sleepForTimeInterval:3]; //开始耗时任务 NSLog(@"开始加载数据"); dispatch_async(dispatch_get_main_queue(), ^{ //调用方法 [self working]; }); }); } - (void) working { //执行block if (self.finishedBlock) { self.finishedBlock(@"<html>"); } } - (void)dealloc { NSLog(@"Tools dealloc"); }@end
推荐 邻家菇凉 的文章《谈谈OC中的循环引用》( 分享自 @简书 )
http://www.jianshu.com/p/48b3d47fac12
转载于:https://blog.51cto.com/zhicongli/1771126