前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS dispatch_after延迟执行导致延迟dealloc

iOS dispatch_after延迟执行导致延迟dealloc

作者头像
清墨
发布2021-04-15 17:04:07
1.8K0
发布2021-04-15 17:04:07
举报
文章被收录于专栏:清墨_iOS分享清墨_iOS分享

我们新建一个NewViewController,在开始的ViewController写如下代码

代码语言:javascript
复制
- (void)viewDidLoad {
    [super viewDidLoad];
    
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    btn.frame = CGRectMake(100, 100, 100, 50);
    btn.backgroundColor = [UIColor brownColor];
    [btn addTarget:self action:@selector(jump) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
    
}

-(void)jump{
    NewViewController *newVC = [[NewViewController alloc]init];
    [self presentViewController:newVC animated:YES completion:nil];
}

然后在NewViewController里:

代码语言:javascript
复制
-(void)dealloc{
    NSLog(@"--------------dealloc");
}

- (void)viewDidLoad {
    [super viewDidLoad];
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    btn.frame = CGRectMake(100, 300, 100, 50);
    btn.backgroundColor = [UIColor brownColor];
    [btn addTarget:self action:@selector(jump) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
    
    __weak typeof(self) weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self log];
        NSLog(@"--------------after");
    });
    
}

-(void)log{
    NSLog(@"--------------log");
}

-(void)jump{
    NSLog(@"--------------dismiss");
    [self dismissViewControllerAnimated:YES completion:nil];
}

运行之后,我们一跳进newVC里面返回,这时候:

image.png

结果说明我们dismiss的时候,newVC还没有被释放,dealloc方法在dispatch_after延迟方法执行之后才会走,原因就是dispatch_after强引用了self(即newVC),等强引用过去,self才能得到释放走dealloc

接下来,我们在dispatch_after里把 self 用 __weak修饰,block里把self改为weakself,我们还是一样的操作流程,看看结果:

代码语言:javascript
复制
- (void)viewDidLoad {
    [super viewDidLoad];
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeCustom];
    btn.frame = CGRectMake(100, 300, 100, 50);
    btn.backgroundColor = [UIColor brownColor];
    [btn addTarget:self action:@selector(jump) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
    
    __weak typeof(self) weakSelf = self;
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [weakSelf log];
        NSLog(@"--------------after");
    });
    
}

image.png

当我们用weak修饰self时,dispatch_after并没有强引用self,所以我们dissmiss时,dealloc立马就会走,然后10s后,dispatch_after的执行函数还是会执行,输出了after,但是没有输出log,这是因为用的weakSelfdissmiss后,newVC已经被释放,这时候代码 [weakSelf log];等同于[nil log];,所以才不会输出log。

使用注意

虽然dispatch_after里直接调用self不会造成循环引用,但当我们dispatch_after延迟时间过长的时候,需要考虑是否要及时释放当前对象,如果需要,尽量使用weakSelf这种方式,如果真有需要用到self完成一些操作再释放的需求,可以按需编写代码。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 使用注意
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档