iOS底层系列之<32>--多线程<二>和RunLoop一起使用

1、GCD和RunLoop一起使用

  • 下面打印结果是什么?
- (void)test4 {
    NSLog(@"3");
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0 );
    
    dispatch_async(queue, ^{
        NSLog(@"1");
        [self performSelector:@selector(test4) withObject:nil afterDelay:0.0];
        NSLog(@"2");

        NSLog(@"--end");
    });
}

打印结果:

2022-01-25 16:30:45.631871+0800 gcd[26764:2852276] 1

2022-01-25 16:30:45.632006+0800 gcd[26764:2852276] 2

2022-01-25 16:30:45.632075+0800 gcd[26764:2852276] --end

  • 为什么任务3不打印呢?

因为[self performSelector:@selector(test4) withObject:nil afterDelay:0.0];这句代码是往RunLoop中添加了定时器,然而,全局队列下的异步函数是开启了一个子线程,子线程是默认不会开启RunLoop的,需要手动开启RunLoop

如下修改:

- (void)test4 {
    NSLog(@"3");
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0 );
    
    dispatch_async(queue, ^{
        NSLog(@"1");
        [self performSelector:@selector(test4) withObject:nil afterDelay:0.0];
        NSLog(@"2");
        
        [[NSRunLoop currentRunLoop] addPort:[[NSPort port] init] forMode:NSDefaultRunLoopMode];
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        NSLog(@"--end");
    });
}

打印结果:(没有打印end)

2022-01-25 16:35:47.531165+0800 gcd[26952:2855439] 1

2022-01-25 16:35:47.531317+0800 gcd[26952:2855439] 2

2022-01-25 16:35:47.531435+0800 gcd[26952:2855439] 3

2、NSThread和RunLoop

下面代码打印是什么?

- (void)test5 {
    NSLog(@"5");
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSThread *thread = [[NSThread alloc] initWithBlock:^{
        NSLog(@"1%@",[NSThread currentThread]);
    }];
    [thread start];
    
    [self performSelector:@selector(test5) onThread:thread withObject:nil waitUntilDone:YES];
}

执行完了任务1后,会崩溃,因为往子线程thread中再次添加任务的时候,子线程已经自动销毁了,线程没有被保活

解决方案,让线程保活!

- (void)viewDidLoad {
    [super viewDidLoad];
}

- (void)test5 {
    NSLog(@"5");
}

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    NSThread *thread = [[NSThread alloc] initWithBlock:^{
        NSLog(@"1%@",[NSThread currentThread]);
        [[NSRunLoop currentRunLoop] addPort:[[NSMachPort port] init] forMode:NSDefaultRunLoopMode];
        [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }];
    [thread start];
    
    [self performSelector:@selector(test5) onThread:thread withObject:nil waitUntilDone:YES];
}

Foundation框架源码学习:GNUStep:GNUstep: Download

也可以参考这个​​​​​​​

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值