OC三方框架05:Masonry探索

张建 lol

Masonry 的 block 中调用 self 会造成循环引用么?

下面我们通过实例分析一下:

1
2
3
4
5
6
7
8
UIButton * btn = [[UIButton alloc] init];
[self.view addSubview:btn];
[btn mas_makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(@100);
make.height.equalTo(@100);
make.left.equalTo(self.view.mas_left);
make.top.equalTo(self.view.mas_top);
}];
  • 控制器 self 会强引用自己的子类 view,即 self -> view
  • btn 实例被添加到 view 上,即 view -> btn
  • 因为 btn 调用了 masonrymas_makeConstaints 方法,其中参数 block 引用了 self

那么问题来了,这里的 blockself 是强引用么?

我们要想知道答案,需进入 mas_makeConstraints 方法中看看它的实现方式才行:

1
2
3
4
5
6
- (NSArray *)mas_makeConstraints:(void(^)(MASConstraintMaker *))block {
self.translatesAutoresizingMaskIntoConstraints = NO;
MASConstraintMaker *constraintMaker = [[MASConstraintMaker alloc] initWithView:self];
block(constraintMaker);
return [constraintMaker install];
}

由源码实现可以知道,block 持有的是 局部临时变量,也就是说当 block 超出作用域就会被销毁。此时的循环链是:self -> view -> btn -> block -> x -> self,没有构成相互持有

  • 类似于 OC 基础动画 Api 的block中使用self访问成员变量:均不会造成循环引用
1
2
3
4
5
[UIView animateWithDuration:2 delay:0 options:UIViewAnimationOptionCurveEaseOut animations:^{
self.label.frame = CGRectMake(0, 0, 100, 50);
} completion:^(BOOL finished) {

}];
  • Post title:OC三方框架05:Masonry探索
  • Post author:张建
  • Create time:2023-05-30 14:00:18
  • Post link:https://redefine.ohevan.com/2023/05/30/OC三方框架/OC三方框架05:Masonry探索/
  • Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.
On this page
OC三方框架05:Masonry探索