关于gcd的一道面试题

2021-09-28  本文已影响0人  奋斗的小马达

1、下面代码打印结果

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    dispatch_queue_t queu = dispatch_get_global_queue(0, 0);
    dispatch_async(queu, ^{
        NSLog(@"1");
        [self performSelector:@selector(test) withObject:nil afterDelay:0.0];
        NSLog(@"3");
    });
}

- (void)test {
    NSLog(@"2");
}

答案:1、3

解析:

[self performSelector:@selector(test) withObject:nil afterDelay:0.0];
这段代码的本质是往runloop中添加定时器 但是子线程的runloop并没有开启
所以当还未等到定时器开始工作 子线程就已经销毁了

2、下面代码打印结果

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    dispatch_queue_t queu = dispatch_get_global_queue(0, 0);
    dispatch_async(queu, ^{
        NSLog(@"1");
        [self performSelector:@selector(test) withObject:nil];
        NSLog(@"3");
    });
}

- (void)test {
    NSLog(@"2");
}

答案:1、2、3

解析:

[self performSelector:@selector(test) withObject:nil];
本质就是:objc_msgSend  代码和 [self test] 本质一样
所以打印结果是:1、2、3

3、下面代码打印结果

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
    dispatch_queue_t queu = dispatch_get_global_queue(0, 0);
    dispatch_sync(queu, ^{
        NSLog(@"1");
        [self performSelector:@selector(test) withObject:nil afterDelay:0.0];
        NSLog(@"3");
    });
}

- (void)test {
    NSLog(@"2");
}

答案:1,3,2

解析:

dispatch_sync 同步执行 所以此时GCD并没有开启新的线程
又由于[self performSelector:@selector(test) withObject:nil afterDelay:0.0];
是开启了定时器,所以runloop在走第一圈的时候的顺序是
 NSLog(@"1")、开启定时器、  NSLog(@"3"); 
然后定时器开始执行 因此又走了    NSLog(@"2");
所以打印结果是:1、3、2




上一篇 下一篇

猜你喜欢

热点阅读