在OC开发中有基本常识,一旦使用block就容易产生循环引用,但很多时候不得不使用,总结整理了容易出现循环引用以及如何避免出现循环引用的方式
@interface TestMemoryLeak ()
{
NSString *_memberVar;// 成员变量
}
@property(nonatomic, assign) NSInteger propertyVar;// 属性变量
@property(nonatomic, copy) dispatch_block_t block; // block
@end
@implementation TestMemoryLeak
- (void)viewDidLoad
{
[super viewDidLoad];
[self testwillLeak];
[self testWillNotLeak];
// 这里不会产生循环引用,因为这个延迟执行block不被self所持有,当然为了方便简单不用考虑是否被持有,统一使用weakSelf也可以
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.block();
});
__weak __typeof(self)weakSelf = self;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
weakSelf.block();
});
}
@end
一、会产生循环引用的使用方式
- (void)testwillLeak
{
// 会产生循环引用的使用方式
self.block = ^(){
NSLog(@"%ld",self.propertyVar);
};
self.block = ^(){
NSLog(@"%ld",self->_propertyVar);
};
self.block = ^(){
NSLog(@"%ld",_propertyVar);
};
self.block = ^(){
NSLog(@"%@",self->_memberVar);
};
self.block = ^(){
NSLog(@"%@",_memberVar);
};
}
二、不会产生循环引用的方式
// 不会产生循环引用的方式
__weak __typeof(self)weakSelf = self;
self.block = ^(){
NSLog(@"%ld",weakSelf.propertyVar);
};
self.block = ^(){
__strong __typeof(weakSelf)strongSelf = weakSelf;
NSLog(@"%ld",strongSelf.propertyVar);
};
self.block = ^(){
__strong __typeof(weakSelf)strongSelf = weakSelf;
NSLog(@"%ld",strongSelf->_propertyVar);
};
self.block = ^(){
__strong __typeof(weakSelf)strongSelf = weakSelf;
NSLog(@"%@",strongSelf->_memberVar);
};
网友评论