__weak弱引用block造成提前释放的问题

使用原生网络请求并进行稍微封装时候出了点问题,总结如下:
   一般来说,使用对象本身持有了block,然后在block中又使用到了这个对象或者这个对象的某个属性,就会造成循环引用,使得内存释放不掉.在这时候就会使用__weak来解除block对对象的强引用.此时block中的对象是弱引用,使得两个都可以释放.
     不过这在和GCD一起使用的时候中间就有个很大的坑,因为block中对对象是弱引用,在block中使用GCD的话,在GCD中使用的对象就是已经弱化的对象,所以会导致这个对象还没开始使用就已经被释放了.看下面例子
#define WeakSelf(type)  __weak typeof(type) weak##type = type;
#define StrongSelf(type)  __strong typeof(type) type = weak##type;

  People *p = [People new];
    p.name = @"piter";
    WeakSelf(p) //弱引用
         p.MyBlock = ^(){
       dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
          NSLog(@"2.%@",weakp.name);
       });
};
   p.MyBlock();

这段代码,在block里面使用了GCD延迟调用,而在GCD代码块里面使用到了weakp这个对象,这个对象本身就是一个弱引用对象,在这里面没有使用就已经被释放了.所以像上面的代码是会输出null的.像这样的问题就需要引入__strong来解决.如下
People *p = [People new];
    p.name = @"piter";
    WeakSelf(p) //弱引用
         p.MyBlock = ^(){
          StrongSelf(p)
       dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
          NSLog(@"2.%@“,p.name);
       });
};
   p.MyBlock();

这样就可以输出并且对象都会被释放.先解释下为什么:这个strong是对block内部的抢引用,不会干扰到block以外.所以不会影响people 和 myblock的释放.而对block内部的弱引用people强引用,就不会导致people提前释放了..
  看AFNetworking也是使用weak加strong管理block内存的.
发布了47 篇原创文章 · 获赞 15 · 访问量 14万+

猜你喜欢

转载自blog.csdn.net/gavin__fan/article/details/52797564
今日推荐