简单快速的理解block的循环引用及__weak的使用条件

block循环引用会导致开辟的内存空间因为相互的引用而无法释放,是占用多余的内存空间的行为。在开发中,我们或多或少的都会遇到block块,但是新手因为接触的少,无法有条理的进行分析来确认是否存在循环引用,下面通过一个简单的代码事例来讲解下block的循环引用以及weak self的使用条件。


首先我先创建了一个Person类,设置其属性并导入ViewController控制器中:

        


我们先来看会导致循环引用的情况:

 #import "ViewController.h"
 #import "Person.h"
 
 @interface ViewController ()
 @end
 
 @implementation ViewController
 
 - (void)viewDidLoad {
     [super viewDidLoad];
     Person *somebody = [[Person alloc] init];
     somebody.name = @"某人";
     somebody.block = ^{
         NSLog(@"%@",somebody.name);
     };
     somebody.block();
 }
 
 @end
解析:通过Person类创建的somebody对象,有个强指针指向着block,block指向着ViewController控制器中的blcok代码块,在ViewController控制器中的block代码块中因为需要打印somebody的名字,所以需要使用到somebody,就使得block代码块有一个强指针指向了somebody,造成了循环引用,因为无法断开其中的任何一条指向,致使它们无法得到释放。图解:



既然我们清楚了循环引用,我们就来断开这样的循环引用,代码调整如下:

 #import "ViewController.h"
 #import "Person.h"
 
 @interface ViewController ()
 @end
 
 @implementation ViewController
 
 - (void)viewDidLoad {
     [super viewDidLoad];
     Person *somebody = [[Person alloc] init];
     somebody.name = @"某人";
     //通过block代码块外部声明一个弱引用,让block代码块内部产生一个弱引用指向somebody对象,解除循环引用
     __weak typeof(somebody) weakSomebody = somebody;
     somebody.block = ^{
         NSLog(@"%@",weakSomebody.name);
     };
     somebody.block();
 }
 
 @end

解析:我们通过__weak typeof(somebody) weakSomebody = somebody;将block代码块中对somebody的强引用转化成了弱引用,当代码执行完毕,block对象会被释放,内存引用关系得到解除。图解:




现在我们应该也明白就是在造成循环的时候,才需要用到__weak,在没有造成循环引用的情况下,我们还是可以在block代码块中使用对象本身的。

但是如果在blcok代码块中存在异步执行或延迟操作的话,__weak的对象很有可能会提前释放,让我们无法完成我们的需求,这种情况下也是不能够使用__weak的,这种情况的解决办法下篇博客进行讲解。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值