美文网首页
老生重谈循环引用

老生重谈循环引用

作者: 阿龍飛 | 来源:发表于2019-01-18 17:53 被阅读19次

    野指针指向一个已删除的对象或未申请访问受限内存区域的指针。特别要指出的是野指针不是空指针。
    一提到 Block 大家肯定都知道要说的是循环引用,在 ARC 中,如果两个对象相互持有对方,就会造成循环引用,导致内存无法释放。在 Block 中,最常用的场景则是,self 持有 block , block 中又持有了 self 。例如下方一段代码:

    - (void)setUpModel{
      XYModel *model = [XYModel new];
      model.dataChanged = ^(NSString *title) {
          self.titleLabel.text = title;                
      };
      self.model = model;
    }
    

    上面的这段代码就会造成循环引用。那我们怎么破除呢?通常的做法都是使用 weakSelf 来处理,即:

    - (void)setUpModel {
      XYModel *model = [XYModel new];
      __weak typeof(self) weakSelf = self;
      model.dataChanged = ^(NSString *title) {
          weakSelf.titleLabel.text = title;   
      };
      self.model = model;
    }
    

    或许你还看到另外一种不是很一样的版本:

    - (void)setUpModel {
      XYModel *model = [XYModel new];
      __weak typeof(self) weakSelf = self;
      model.dataChanged = ^(NSString *title) {
          __strong typeof(self) strongSelf = weakSelf;
          strongSelf.titleLabel.text = title;   
      };
      self.model = model;
    }
    

    对比一下,多了一个 strongSelf 。那为什么又要多加一个 strongSelf 呢?

    __weak __typeof__(self) weakSelf = self;
    dispatch_group_async(_operationsGroup, _operationsQueue, ^{
      [weakSelf doSomething];
      [weakSelf doSomethingElse];
    });
    

    在 doSomething 时, weakSelf 不会被释放,但是在 doSomethingElse 时,weakSelf 有可能被释放。
    在这里就需要用到 strongSelf ,使用 __strong 确保在 Block 内, strongSelf 不会被释放。

    小结

    在使用 Block 时,如遇到循环引用问题,可以使用 __weak 来破除循环引用。
    如果在 Block 内需要多次访问 __weak 变量,则需要使用 __strong 来保持变量不会被释放。

    相关文章

      网友评论

          本文标题:老生重谈循环引用

          本文链接:https://www.haomeiwen.com/subject/ittodqtx.html