iOS的weakSelf与strongSelf

避免循环引用的标准做法:weakSelf+strongSelf

假设我们的类有一个属性叫做 model, 我们想要当 model 中的 data 变化的时候,有一个 label 的 text 会随之改变,为了达到这目的,我们设置 model :

 

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

- (void)viewDidLoad {
    [super viewDidLoad];
    
    printf("retain count:%ld\n", CFGetRetainCount((__bridge CFTypeRef)(self)));
    
    [self setUpModel];
    
    printf("retain count:%ld\n", CFGetRetainCount((__bridge CFTypeRef)(self)));
}

果然,打印显示,引用计数+1了

 

image.png

为啥?我们的 ViewController 持有了 model , model 持有了一个 Block , 这个 Block 又持有了 ViewController ,导致了循环引用。so通过添加 _weak 和 _strong 修饰的变量来打破循环引用,代码如下:

 

- (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;
}

果然,效果很理想

 

image.png

为什么要用strongSelf

其实大家可以试一下,直接用weakSelf,你会发现引用计数不变,那为啥要加这玩意儿,难道为了装逼?!主要是有时候weakSelf在block里在执行doSomething还存在,但在执行doMorething前,可能会被释放了,故为了保证self在block执行过程里一直存在,对他强引用strongSelf,一句话的事情

 

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

如果出现双层block嵌套甚至更多怎么办😰

看下面的例子,出现了两个block

 

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

结果引用计数+1了,shit,我们还需要对strongSelf再进行一次weakSelf-strongSelf
,如下

 

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

这样,就避免的引用循环,总结一下,不管都多少个block嵌套,皆按此法

更装逼的写法weakify + strongify

weakify 和 strongify其实是这样:

 

#define weakify(var) __weak typeof(var) XYWeak_##var = var;
#define strongify(var) \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wshadow\"") \
__strong typeof(var) var = XYWeak_##var; \
_Pragma("clang diagnostic pop")
\\define加入反斜杠\表示换行意思

具体按下面使用:

 

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

以上代码翻译下:

 

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



作者:踏云小子
链接:https://www.jianshu.com/p/4d7410ad568f
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值