iOS block 的循环引用以及项目中遇见的情况

1.并不是说block当中使用了self就一定会造成循环引用,例如使用系统的方法

+ (void)animateWithDuration:(NSTimeInterval)duration animations:(void (^)(void))animations NS_AVAILABLE_IOS(4_0); // delay = 0.0, options = 0, completion = NULL

可以这样理解,当前的self是无法持有一个类对象的。

测试方式

a.新建一个项目ViewController为根控制器,并且新建FirstVC

b.在ViewDidLoad中使用

  [UIView animateWithDuration:5 animations:^{ NSLog(@"第一次打印  %@",self);    }];该方法

c.由ViewController模态出FirstVC,然后FirstVC在dismiss

d.查看FirstVC中

- (void)dealloc{
    NSLog(@"%s --> FirstVC -dealloc",__func__);
}

这段代码是否执行。

2.有些系统方法当中使用self,也是会造成循环引用的,例如在FirstVC中写上如下代码

在FirstVC  dissmis的时候dealloc方法并不会执行,解决方式就是使用__weak typeof(self) weakSelf = self;这种方式来解决。

3.除了系统方法,在使用AFNetWoking的时候也可以在其中使用self,测试方式和上面的测试方式一样,一般我们进行的网络请求都是使用一个网络请求类,当前的self并不会持有那个类,所以不会造成循环引用,但是我又做了一个测试,那就是让当前的FirstVC中持有这个请求类对象

 [[NSNotificationCenter defaultCenter] addObserverForName:@"123" object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * _Nonnull note) {
        NSLog(@"第二次打印  %@",self);
    }];

发现在FirstVC dissmis的时候 dealloc方法仍然会执行,应该是AFN底层有一些特殊的处理。

4.在自己定义block的时候往往会遇见循环引用的问题,例如在FirstzVC中定义了一个block

   _session = [AFHTTPSessionManager manager];
    [_session POST:@"www.baidu.com" parameters:nil progress:^(NSProgress * _Nonnull uploadProgress) {
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
     
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        NSLog(@"第二次打印  %@",self.view);
    }];
//这段代码是写在FirstVC中的

这段代码写在FirstVC中,如果block中使用self就会造成循环引用

如果testblock的实现写在ViewController当中,是不会造成循环引用的

5.有时会在block内部写上__strong typeof(weakSelf) strongSelf = weakSelf;这句话,这句话的作用是强引用一下这个弱指针,使其不立刻释放,在项目中具体的应用如下代码

    _name = @"123";
    __weak typeof(self) weakSelf = self;
    _testblock = ^{
        __strong typeof(weakSelf) strongSelf = weakSelf;
        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(7 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            //NSLog(@"第五次打印  %@",weakSelf.name);
 
            NSLog(@"第五次打印  %@",strongSelf.name);
        });
    };
    self.testblock();

这段代码写在FirstVC当中,在FirstVC dissmis的时候还没执行这个延迟函数就用到了strongSelf,如果单独使用weakSelf是打印不出来name这个属性的。

转载于:https://my.oschina.net/u/3937044/blog/1935189

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值