如何解决block的循环引用,why
AV8D know, 在block中使用self经常会造成循环引用,那我们该如何解决循环引用的问题呢?
通常的做法是用__weak关键字生成一个弱引用,然后在block中使用这个弱引用:
__weak typeof(self)weakSelf =self;
self.demoBlock= ^{[weakSelf.tableView reloadData];
};
这个self造成循环引用大家都get了,可能大家会忽略,在block中直接使用类的私有成员变量也会造成循环引用:
例如ViewController中有一个block类型的成员属性someBlock,另外一个是私有变量_children:
@interfaceViewController:UIViewController
{
NSMutableArray*_children;
}
@property(copy,nonatomic)void(^someBlock)();
其实在默认情况下,ViewController中的_children是使用__strong修饰的,例2就等价于下面的例3
// 例3
@interfaceViewController:UIViewController
{
__strong NSMutableArray *_children;
}
@property(copy,nonatomic)void(^someBlock)();
【如何解决block的循环引用,why】这个时候,在为someBlock赋值的时候,直接使用__children就会造成retain cycle:
// 例4
- (void)viewDidLoad
{
[superviewDidLoad];
self.someBlock= ^{
[_children addObject:@"Tom"];
// 上面代码就等价于下面一行// [self->_children addObject:@"Tom"];
};
}
要打破此循环引用,也要用到清单1中使用的方法,不同的是,必须在block内使用__strong的self:
// 例5
- (void)viewDidLoad
{
[superviewDidLoad];
__weak typeof(self) wself =self;
self.someBlock= ^{
__strong typeof(wself) sself = wself;
[sself->_children addObject:@"Tom"];
};
}
小伙伴们get了吗,作为一个真正的iOS码农,这个坑必须要理解的哦!
推荐阅读
- parallels|parallels desktop 解决网络初始化失败问题
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- 如何寻找情感问答App的分析切入点
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- SpringBoot调用公共模块的自定义注解失效的解决
- 解决SpringBoot引用别的模块无法注入的问题
- 如何在Mac中的文件选择框中打开系统隐藏文件夹
- 漫画初学者如何学习漫画背景的透视画法(这篇教程请收藏好了!)