IOS开发

Block内存管理

2020-08-10  本文已影响0人  越天高

在平时的开发中我们经常使用block来传值和事件传递,但是block的使用很容易造成循环引用(我引用你 你引用我 就会造成循环引用),产生内存泄漏;
block很容易产生循环引用,跟执行或者不执行block无关。
只要是写了产生循环引用的代码,即使不执行,也会导致引用对象无法被释放,我们平时写block的生命属性的时候,会选择用copy或者是strong来使用,在MRC中我们会选择使用copy,在ARC中我们使用cop又或者使用strong都可以,最好使用还是strong因为copy的底层实现还是会进行一些判断,相比之后性能会差点。

  1. 我们定义的局部的block引用self的属性,是不会造成循环引用的,因为self本身没有对我们的block强引用,所以没有造成闭环
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    void (^block)(void) = ^{
        self.age++;
        NSLog(@"%d",self.age);
    };
    block();
}

- (void)dealloc
{
    NSLog(@"dealloc");
}
/***********/
- (void)viewDidLoad
{
    [super viewDidLoad];
    
    void (^block)(void) = ^{
        self.age++;
        NSLog(@"%d",self.age);
    };
    _block = block;
    
}

/******如果我们呢把block里面的self.age改成_age,
同样还是会造成循环引用,因为他的本质还是会调用 self=>_age
******/

如果我们在 定义一个weak使用的话就不会造成循环,
但是注意,如果block里面的操作有延时操作的话,不能直接使用weakSelf,
因为控制器有可能会销毁,这是再执行操作会造成拿不到数据
应该在里面再对这个弱指针强引用一次避免他提前销毁

 void (^block)(void) = ^
     {
//         __strong typeof (weakSelf) strongSelf = weakSelf;
        weakSelf.age = 90;
         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^
         {
             
             NSLog(@"----%d",weakSelf.age);
            //这时候的weakSelf已经是空的了,null
             NSLog(@"----%@",weakSelf);

         });
    };
    _block = block;
    block();

//我们在block中使用要再加上这句话
__strong typeof (weakSelf) strongSelf = weakSelf;
里面使用strongSelf这样保证了self不会在执行延时操作之前被销毁

static  void(^globalBlock)(void);

 globalBlock = ^
    {
        NSLog(@"%ld", self.age);
    };
上一篇 下一篇

猜你喜欢

热点阅读