美文网首页iOS新知识
怎么防止Block的循环引用

怎么防止Block的循环引用

作者: Silence_xl | 来源:发表于2020-05-20 20:23 被阅读0次

    考虑到多线程情况,通过使用强引用 self 来引用该弱引用,这时如果 self 不为 nil 就会 retain self,以防止在后面的使用过程中 self 被释放;然后在之后的 block 块中使用该强引用 self,注意在使用前要对 self 进行了 nil 检测,因为多线程环境下在用弱引用 wself 对强引用 self 赋值时,弱引用 wself 可能已经为 nil 了。
    通过这种手法,block 就不会持有 self 的引用,从而打破了循环引用。

    第一种解决方法(strong weak dance)
    //strong weak dance
    typedef void (^LGBlock) (void);
    
    @interface ViewController ()
    
    @property (nonatomic,copy) LGBlock block;
    @property (nonatomic,copy) NSString *name;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.name = @"Silence";
       
        __weak typeof(self) weakSelf = self;
        self.block = ^{
            __strong typeof(self) strongSelf = weakSelf;
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                strongSelf.name = @"longge";
                NSLog(@"%@",strongSelf.name);
            });
        };
        self.block();
        
    }
    
    第二种方法(__block)
    typedef void (^LGBlock) (void);
    
    @interface ViewController ()
    
    @property (nonatomic,copy) LGBlock block;
    @property (nonatomic,copy) NSString *name;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.name = @"Silence";
       
        __block ViewController *vc = self;
        self.block = ^{
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                NSLog(@"%@",vc.name);
                vc = nil;
            });
        };
        self.block();
        
    }
    
    第三种方法(作为参数)
    typedef void (^LGBlock) (ViewController *);
    
    @interface ViewController ()
    
    @property (nonatomic,copy) LGBlock block;
    @property (nonatomic,copy) NSString *name;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        self.name = @"Silence";
       
        self.block = ^(ViewController *vc) {
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                NSLog(@"%@",vc.name);
            });
        };
        self.block(self);
        
    }
    

    相关文章

      网友评论

        本文标题:怎么防止Block的循环引用

        本文链接:https://www.haomeiwen.com/subject/kianohtx.html