美文网首页数据传递iOS Dev代码质量
避免循环引用的坑:在Block中使用私有成员变量

避免循环引用的坑:在Block中使用私有成员变量

作者: botherbox | 来源:发表于2016-01-11 11:51 被阅读1882次

大家都知道,在block中使用self经常会造成循环引用。通常解决办法就是使用__weak关键字先生成一个弱引用,然后再在block中使用:

// 清单1
__weak typeof(self) wself = self;
self.demoBlock = ^{
   [wself.tableView reloadData];
};

但是在block中直接使用类的私有成员变量也会造成循环引用:
例如ViewController中有一个block类型的成员属性someBlock,另外一个是私有变量_children:

// 清单2
@interface ViewController : UIViewController
{
     NSMutableArray *_children;
}
@property (copy, nonatomic) void(^someBlock)();

其实在默认情况下,ViewController中的_children是使用__strong修饰的,清单2就等价于下面的清单3

// 清单3
@interface ViewController : UIViewController
{
     __strong NSMutableArray *_children;
}
@property (copy, nonatomic) void(^someBlock)();

这个时候,在为someBlock赋值的时候,直接使用__children 就会造成retain cycle:

// 清单4
- (void)viewDidLoad
{
  [super viewDidLoad];
  self.someBlock = ^{
    [_children addObject:@"Tom"];
    // 上面代码就等价于下面一行
    // [self->_children addObject:@"Tom"];
  };
}

要打破此循环引用,也要用到清单1中使用的方法,不同的是,必须在block内使用__strong的self:

 // 清单5
- (void)viewDidLoad
{
  [super viewDidLoad];
  __weak typeof(self) wself = self;
  self.someBlock = ^{
    __strong typeof(wself) sself = wself;
    [sself->_children addObject:@"Tom"];
  };
}

相关文章

网友评论

  • HelloRyan: __weak typeof(self) wself = self;之后再 __strong typeof(wself) sself = wself; 这个应该怎么理解?
    奔跑的蔬菜:@奔跑的蔬菜 不过解决了我的问题!
    奔跑的蔬菜:@codebreak 还是不是很理解 :joy:
    8c371490966e:@HelloRyan __weakSelf在block里面有可能执行完一次被释放,所有要用__strong来确保在block内weakSelf不会被释放,但是此block内只有一句话,为什么要用__strong呢?因为用weakSelf->会引发这一种错误:Dereferencing a __weak pointer is not allowed due to possible null value caused by race condition, assign it to a strong variable first. (对一个 __weak 指针的解引用不允许的,因为可能在竞态条件里面变成 null, 所以先把他定义成 strong 的属性),所以必须用__strong来确保为强引用。
  • 小橙圈:今天刚碰到这个坑..一开始怀疑是这个问题没往这方面想,最后一步一步每个步骤都过发现是这个问题....

本文标题:避免循环引用的坑:在Block中使用私有成员变量

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