iOS中Block的循环引用问题

iOS中Block的循环引用问题

每周总结,第一周开始啦,最近在看AFNetworking源码时,看到了__strong的使用,很惭愧的说在平时开发中从来没有使用过__strong self ,除此之外,发现自己对Block的循环引用理解的也不深刻,今天就总结下block的循环引用问题

AFNetworking中__strongSelf应用如下


AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
        __strong __typeof(weakSelf)strongSelf = weakSelf;
        strongSelf.networkReachabilityStatus = status;
        if (strongSelf.networkReachabilityStatusBlock) {
            strongSelf.networkReachabilityStatusBlock(status);
        }
    };

本文将从以下几个方面介绍ARC下block的循环引用问题:
1. 什么是循环引用
2. 循环引用的结果
3. ARC下Block怎样产生的循环引用
4. 怎么样解决循环引用

1、什么是循环引用?
两个对象相互持有,导致两个对象都不能释放,造成内存泄漏。

2、如何产生了循环引用
观察以下代码存在些什么问题

@interface ViewController ()
@property (nonatomic, copy) void(^ testBlock)();
@end

@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.testBlock = ^(void){
        [self doSomeThing];
    };
}
-(void)doSomeThing{
    NSLog(@"you are doing something");
}
@end

在上述代码中,XCode编译后提示[self doSomeThing],这一行可能会导致循环引用。
因为无论testBlock是copy还是strong属性,self都强引用了testBlock,在testBlock内部又调用了self,此时,testBlock强引用self(self的引用计数+1),导致ViewController实例无法被释放,因为自身的变量的引用计数永远大于1,循环引用。

为了解决这种问题,可以声明一个__weak变量指向self,在blcok中使用这个__weak变量,就不会导致self的引用计数+1,不会出现循环引用的问题了。

@interface ViewController ()
@property (nonatomic, copy) void(^ testBlock)();
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    __weak __typeof(self)weakSelf = self;

    self.testBlock = ^(void){
        [weakSelf doSomeThing];
    };
}

-(void)doSomeThing{
    NSLog(@"you are doing something");
}

@end

循环引用问题解决了,但是这时还有其他的问题,当你加了weakSelf后,Block中的self随时都会有被释放的可能,所以会出现一种情况,在异步调用的时候,执行到Block代码块时,self可能已经释放为nil了,所以为了避免这种情况发生,我们会重新strong self。一般情况下,我们都应该这么做,毕竟这么做是没什么风险,除非你不关心self在执行过程中变成nil,或者你确定它不会变成nil。

__weak __typeof(self)weakSelf = self;
self.testBlock = ^{
    __strong __typeof(weakSelf)strongSelf = weakSelf;
    [strongSelf doSomeThing];
}];

weakSelf是为了block弱引用self,避免循环引用,而再声明一个strongSelf是因为一旦进入block执行,就不允许self在这个执行过程中释放。block执行完后这个strongSelf会自动释放,没有循环引用问题。

到此,有关本人对weakSelf的使用历程就介绍完毕啦,后续学习到新的知识,再更新,收车。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值