常见循环引用探究

2019-04-10  本文已影响0人  独孤流

在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);
    };
上一篇 下一篇

猜你喜欢

热点阅读