区块链技术博客
www.b2bchain.cn

iOS面试题目解析19 – GCD题目求职学习资料

本文介绍了iOS面试题目解析19 – GCD题目求职学习资料,有助于帮助完成毕业设计以及求职,是一篇很好的资料。

对技术面试,学习经验等有一些体会,在此分享。

1.下列代码的输出

__block int a = 0; while (a < 5) {     dispatch_async(dispatch_get_global_queue(0, 0), ^{         a++;     }); } NSLog(@"%d", a);

答案:>= 5的值。

原因:dispatch_async 异步任务,执行完成的时间不确定。

2.下面代码的输出

dispatch_queue_t serial_queue = dispatch_queue_create("com.xxx.test", DISPATCH_QUEUE_SERIAL);  dispatch_sync(serial_queue, ^{     sleep(3);     NSLog(@"task 1 %@", NSThread.currentThread); });  dispatch_sync(serial_queue, ^{     NSLog(@"task 2 %@", NSThread.currentThread); });  dispatch_async(serial_queue, ^{     NSLog(@"task 3 %@", NSThread.currentThread); });  dispatch_async(serial_queue, ^{     NSLog(@"task 4 %@", NSThread.currentThread); });  NSLog(@"test end");

答案:task 1 -> task 2 -> test end -> task 3 和 4 的顺序不确定。

原因:dispatch_sync 是同步,会阻塞当前线程,由于 DISPATCH_QUEUE_SERIAL 是串行队列,所以task 1 和 2 会串行按顺序执行,而 dispatch_async是异步任务,不会阻塞当前线程,会在其它线程一个一个执行,则顺序不一定,取决于任务耗时。

3.下列代码的输出

dispatch_queue_t queue = dispatch_queue_create("com.xxx.test", DISPATCH_QUEUE_CONCURRENT); NSMutableArray *marr = [NSMutableArray array]; for (int i = 0; i < 1000; i++) {     dispatch_async(queue, ^{         [marr addObject:@(i)];     }); } NSLog(@"%lu", marr.count);

答案:会 crash
原因:dispatch_async 异步任务 + DISPATCH_QUEUE_CONCURRENT 并行队列,会开辟多个线程执行,调用 marr 的 addObject: 方法,多个线程抢占同一个资源,会 crash。

4.下列代码的运行结果

- (void)viewDidLoad {    [super viewDidLoad];    NSLog(@"1");    dispatch_sync(dispatch_get_main_queue(), ^{        NSLog(@"2");    });    NSLog(@"3"); }

答案:输出 1 后发生死锁,主线程卡死。
原因:同步任务会阻塞当前线程,然后把 Block 中的任务放到指定的队列中执行,只有等到 Block 中的任务完成后才会让当前线程继续往下运行。那么这里的步骤就是:打印完第一句后,dispatch_sync 立即阻塞当前的主线程,然后把 Block 中的任务放到 main_queue 中,将 main_queue 中的任务会被取出来放到主线程中执行,但主线程这个时候已经被阻塞了,所以 Block 中的任务就不能完成,它不完成,dispatch_sync 就会一直阻塞主线程,这就是死锁现象。导致主线程一直卡死。

5.下面代码的运行结果

dispatch_queue_t queue = dispatch_get_global_queue(0, 0); dispatch_async(queue, ^{     NSLog(@"1");     dispatch_sync(queue, ^{         NSLog(@"2");     });     NSLog(@"3"); }); NSLog(@"4");

答案:4 -> 1 -> 2 -> 3
原因:dispatch_sync 为同步任务,在dispatch_get_global_queue中执行,所以3会在4的前面执行。

6.下面代码的运行结果

dispatch_queue_t queue = dispatch_queue_create("com.xxx.xxx", DISPATCH_QUEUE_SERIAL); dispatch_async(queue, ^{     NSLog(@"1");     dispatch_sync(queue, ^{         NSLog(@"2");     });     NSLog(@"3"); }); NSLog(@"4");

答案:会打印 “之前”、“之后” 和 “sync 之前”,然后死锁。
原因:DISPATCH_QUEUE_SERIAL 创建了串行队列。由于 dispatch_async 是异步任务,则不阻塞当前线程,“之前”、“之后”会被执行。同时其中的“sync 之前”也会被执行。然后 dispatch_sync 是同步执行,于是它所在的线程会被阻塞,一直等到 sync 里的任务执行完才会继续往下。于是 sync 就把自己 Block 中的任务放到 queue 中,但是 queue 是一个串行队列,一次执行一个任务,所以 sync 的 block 必须等到前一个任务执行完毕,可万万没想到的是 queue 正在执行的任务就是被 sync 阻塞了的那个。于是又发生了死锁。所以 sync 所在的线程被卡死了。剩下的两句代码自然不会打印。

7.下面代码的运行结果。把 0 换成 1 或者 2 后是什么结果?

dispatch_semaphore_t t1 = dispatch_semaphore_create(0);  dispatch_async(dispatch_get_global_queue(0, 0), ^{     NSLog(@"1");     dispatch_semaphore_signal(t1); }); dispatch_semaphore_wait(t1, DISPATCH_TIME_FOREVER);  dispatch_async(dispatch_get_global_queue(0, 0), ^{     NSLog(@"2");     sleep(2);     dispatch_semaphore_signal(t1); }); dispatch_semaphore_wait(t1, DISPATCH_TIME_FOREVER);  dispatch_async(dispatch_get_global_queue(0, 0), ^{     NSLog(@"3");     dispatch_semaphore_signal(t1); });

答案:1 -> 2 -> 3 顺序打印
原因:将最大并发数量设置为 0 后,就成了串行队列,按顺序执行。

将 0 修改为 1 和 2 后,顺序就不一定了,因为多个异步任务可以同时执行。

8.下面代码的运行结果? 将 performSelector: 换成 performSelectorOnMainThread: 呢?

- (void)viewDidLoad {     [super viewDidLoad];      dispatch_async(dispatch_get_global_queue(0, 0), ^{         NSLog(@"1");          [self performSelector:@selector(test) withObject:nil afterDelay:0];          NSLog(@"3");     }); }

答案:输出 1 3,不会输出 2
原因:performSelecter: 在子线程是不起作用的,因为子线程默认没有 Runloop,也就没有 Timer。而 performSelecter: 的原理是内部会创建一个 Timer 并添加到当前线程的 RunLoop 中。所以如果当前线程没有 RunLoop,则这个方法会失效。解决办法是采用 GCD timer。参考

performSelector: 换成 performSelectorOnMainThread:的结果:

- (void)viewDidLoad {     [super viewDidLoad];      dispatch_async(dispatch_get_global_queue(0, 0), ^{         NSLog(@"1");          [self performSelectorOnMainThread:@selector(test) withObject:nil waitUntilDone:YES];          NSLog(@"3");     }); }  - (void)test {     NSLog(@"2"); }

答案:输出 1 2 3
原因:该方法回强制回主线程,设置 waitUntilDone 参数为 YES,则表示等待主线程任务执行完成之后再回来执行。如果设置为 NO,则输出 1 3 2。

9.下面代码的运行结果?

dispatch_async(dispatch_get_main_queue(), ^{     NSLog(@"1, thrad: %@", [NSThread currentThread]); });  dispatch_async(dispatch_get_main_queue(), ^{     NSLog(@"2, thrad: %@", [NSThread currentThread]); });  dispatch_async(dispatch_get_main_queue(), ^{     NSLog(@"3, thrad: %@", [NSThread currentThread]); });

答案:1 2 3 并且线程都是主线程。
原因:主队列是串行队列,放在串行队列中的任务不会开辟新的线程执行。

10. 有一个 generateContent 比较耗时的方法,会生成特定的内容返回,现在需要调用这个方法:1. 如果方法立马返回,则立即返回这内容 2. 如果 3s 未返回,则返回为空。如何实现?

可以使用信号量 dispatch_semaphore_tdispatch_queue_t 实现:

信号量 dispatch_semaphore_t实现

dispatch_async 异步调用 generateContent 方法,方法执行完成后进行信号量 singal ,信号量 dispatch_semaphore_t wait 时候可以设置超时时间为 3s即可:

“`objc

  • (NSString *)getSomeContent {
    __block NSString *str;
    dispatch_semaphore_t sempahore = dispatch_semaphore_create(0);
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_async(queue, ^{ // 异步调用
    str = [self generateContent]; // 可能的耗时操作
    dispatch_semaphore_signal(sempahore);
    });

    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC); // 设置 3s 超时
    dispatch_semaphore_wait(sempahore, time);

    return str;
    }

  • (NSString *)generateContent {
    sleep(5); // 模拟耗时操作

1.下列代码的输出

__block int a = 0; while (a < 5) {     dispatch_async(dispatch_get_global_queue(0, 0), ^{         a++;     }); } NSLog(@"%d", a);

答案:>= 5的值。

原因:dispatch_async 异步任务,执行完成的时间不确定。

2.下面代码的输出

dispatch_queue_t serial_queue = dispatch_queue_create("com.xxx.test", DISPATCH_QUEUE_SERIAL);  dispatch_sync(serial_queue, ^{     sleep(3);     NSLog(@"task 1 %@", NSThread.currentThread); });  dispatch_sync(serial_queue, ^{     NSLog(@"task 2 %@", NSThread.currentThread); });  dispatch_async(serial_queue, ^{     NSLog(@"task 3 %@", NSThread.currentThread); });  dispatch_async(serial_queue, ^{     NSLog(@"task 4 %@", NSThread.currentThread); });  NSLog(@"test end");

答案:task 1 -> task 2 -> test end -> task 3 和 4 的顺序不确定。

原因:dispatch_sync 是同步,会阻塞当前线程,由于 DISPATCH_QUEUE_SERIAL 是串行队列,所以task 1 和 2 会串行按顺序执行,而 dispatch_async是异步任务,不会阻塞当前线程,会在其它线程一个一个执行,则顺序不一定,取决于任务耗时。

3.下列代码的输出

dispatch_queue_t queue = dispatch_queue_create("com.xxx.test", DISPATCH_QUEUE_CONCURRENT); NSMutableArray *marr = [NSMutableArray array]; for (int i = 0; i < 1000; i++) {     dispatch_async(queue, ^{         [marr addObject:@(i)];     }); } NSLog(@"%lu", marr.count);

答案:会 crash
原因:dispatch_async 异步任务 + DISPATCH_QUEUE_CONCURRENT 并行队列,会开辟多个线程执行,调用 marr 的 addObject: 方法,多个线程抢占同一个资源,会 crash。

4.下列代码的运行结果

- (void)viewDidLoad {    [super viewDidLoad];    NSLog(@"1");    dispatch_sync(dispatch_get_main_queue(), ^{        NSLog(@"2");    });    NSLog(@"3"); }

答案:输出 1 后发生死锁,主线程卡死。
原因:同步任务会阻塞当前线程,然后把 Block 中的任务放到指定的队列中执行,只有等到 Block 中的任务完成后才会让当前线程继续往下运行。那么这里的步骤就是:打印完第一句后,dispatch_sync 立即阻塞当前的主线程,然后把 Block 中的任务放到 main_queue 中,将 main_queue 中的任务会被取出来放到主线程中执行,但主线程这个时候已经被阻塞了,所以 Block 中的任务就不能完成,它不完成,dispatch_sync 就会一直阻塞主线程,这就是死锁现象。导致主线程一直卡死。

5.下面代码的运行结果

dispatch_queue_t queue = dispatch_get_global_queue(0, 0); dispatch_async(queue, ^{     NSLog(@"1");     dispatch_sync(queue, ^{         NSLog(@"2");     });     NSLog(@"3"); }); NSLog(@"4");

答案:4 -> 1 -> 2 -> 3
原因:dispatch_sync 为同步任务,在dispatch_get_global_queue中执行,所以3会在4的前面执行。

6.下面代码的运行结果

dispatch_queue_t queue = dispatch_queue_create("com.xxx.xxx", DISPATCH_QUEUE_SERIAL); dispatch_async(queue, ^{     NSLog(@"1");     dispatch_sync(queue, ^{         NSLog(@"2");     });     NSLog(@"3"); }); NSLog(@"4");

答案:会打印 “之前”、“之后” 和 “sync 之前”,然后死锁。
原因:DISPATCH_QUEUE_SERIAL 创建了串行队列。由于 dispatch_async 是异步任务,则不阻塞当前线程,“之前”、“之后”会被执行。同时其中的“sync 之前”也会被执行。然后 dispatch_sync 是同步执行,于是它所在的线程会被阻塞,一直等到 sync 里的任务执行完才会继续往下。于是 sync 就把自己 Block 中的任务放到 queue 中,但是 queue 是一个串行队列,一次执行一个任务,所以 sync 的 block 必须等到前一个任务执行完毕,可万万没想到的是 queue 正在执行的任务就是被 sync 阻塞了的那个。于是又发生了死锁。所以 sync 所在的线程被卡死了。剩下的两句代码自然不会打印。

7.下面代码的运行结果。把 0 换成 1 或者 2 后是什么结果?

dispatch_semaphore_t t1 = dispatch_semaphore_create(0);  dispatch_async(dispatch_get_global_queue(0, 0), ^{     NSLog(@"1");     dispatch_semaphore_signal(t1); }); dispatch_semaphore_wait(t1, DISPATCH_TIME_FOREVER);  dispatch_async(dispatch_get_global_queue(0, 0), ^{     NSLog(@"2");     sleep(2);     dispatch_semaphore_signal(t1); }); dispatch_semaphore_wait(t1, DISPATCH_TIME_FOREVER);  dispatch_async(dispatch_get_global_queue(0, 0), ^{     NSLog(@"3");     dispatch_semaphore_signal(t1); });

答案:1 -> 2 -> 3 顺序打印
原因:将最大并发数量设置为 0 后,就成了串行队列,按顺序执行。

将 0 修改为 1 和 2 后,顺序就不一定了,因为多个异步任务可以同时执行。

8.下面代码的运行结果? 将 performSelector: 换成 performSelectorOnMainThread: 呢?

- (void)viewDidLoad {     [super viewDidLoad];      dispatch_async(dispatch_get_global_queue(0, 0), ^{         NSLog(@"1");          [self performSelector:@selector(test) withObject:nil afterDelay:0];          NSLog(@"3");     }); }

答案:输出 1 3,不会输出 2
原因:performSelecter: 在子线程是不起作用的,因为子线程默认没有 Runloop,也就没有 Timer。而 performSelecter: 的原理是内部会创建一个 Timer 并添加到当前线程的 RunLoop 中。所以如果当前线程没有 RunLoop,则这个方法会失效。解决办法是采用 GCD timer。参考

performSelector: 换成 performSelectorOnMainThread:的结果:

- (void)viewDidLoad {     [super viewDidLoad];      dispatch_async(dispatch_get_global_queue(0, 0), ^{         NSLog(@"1");          [self performSelectorOnMainThread:@selector(test) withObject:nil waitUntilDone:YES];          NSLog(@"3");     }); }  - (void)test {     NSLog(@"2"); }

答案:输出 1 2 3
原因:该方法回强制回主线程,设置 waitUntilDone 参数为 YES,则表示等待主线程任务执行完成之后再回来执行。如果设置为 NO,则输出 1 3 2。

9.下面代码的运行结果?

dispatch_async(dispatch_get_main_queue(), ^{     NSLog(@"1, thrad: %@", [NSThread currentThread]); });  dispatch_async(dispatch_get_main_queue(), ^{     NSLog(@"2, thrad: %@", [NSThread currentThread]); });  dispatch_async(dispatch_get_main_queue(), ^{     NSLog(@"3, thrad: %@", [NSThread currentThread]); });

答案:1 2 3 并且线程都是主线程。
原因:主队列是串行队列,放在串行队列中的任务不会开辟新的线程执行。

10. 有一个 generateContent 比较耗时的方法,会生成特定的内容返回,现在需要调用这个方法:1. 如果方法立马返回,则立即返回这内容 2. 如果 3s 未返回,则返回为空。如何实现?

可以使用信号量 dispatch_semaphore_tdispatch_queue_t 实现:

信号量 dispatch_semaphore_t实现

dispatch_async 异步调用 generateContent 方法,方法执行完成后进行信号量 singal ,信号量 dispatch_semaphore_t wait 时候可以设置超时时间为 3s即可:

“`objc

  • (NSString *)getSomeContent {
    __block NSString *str;
    dispatch_semaphore_t sempahore = dispatch_semaphore_create(0);
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_async(queue, ^{ // 异步调用
    str = [self generateContent]; // 可能的耗时操作
    dispatch_semaphore_signal(sempahore);
    });

    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC); // 设置 3s 超时
    dispatch_semaphore_wait(sempahore, time);

    return str;
    }

  • (NSString *)generateContent {
    sleep(5); // 模拟耗时操作

1.下列代码的输出

__block int a = 0; while (a < 5) {     dispatch_async(dispatch_get_global_queue(0, 0), ^{         a++;     }); } NSLog(@"%d", a);

答案:>= 5的值。

原因:dispatch_async 异步任务,执行完成的时间不确定。

2.下面代码的输出

dispatch_queue_t serial_queue = dispatch_queue_create("com.xxx.test", DISPATCH_QUEUE_SERIAL);  dispatch_sync(serial_queue, ^{     sleep(3);     NSLog(@"task 1 %@", NSThread.currentThread); });  dispatch_sync(serial_queue, ^{     NSLog(@"task 2 %@", NSThread.currentThread); });  dispatch_async(serial_queue, ^{     NSLog(@"task 3 %@", NSThread.currentThread); });  dispatch_async(serial_queue, ^{     NSLog(@"task 4 %@", NSThread.currentThread); });  NSLog(@"test end");

答案:task 1 -> task 2 -> test end -> task 3 和 4 的顺序不确定。

原因:dispatch_sync 是同步,会阻塞当前线程,由于 DISPATCH_QUEUE_SERIAL 是串行队列,所以task 1 和 2 会串行按顺序执行,而 dispatch_async是异步任务,不会阻塞当前线程,会在其它线程一个一个执行,则顺序不一定,取决于任务耗时。

3.下列代码的输出

dispatch_queue_t queue = dispatch_queue_create("com.xxx.test", DISPATCH_QUEUE_CONCURRENT); NSMutableArray *marr = [NSMutableArray array]; for (int i = 0; i < 1000; i++) {     dispatch_async(queue, ^{         [marr addObject:@(i)];     }); } NSLog(@"%lu", marr.count);

答案:会 crash
原因:dispatch_async 异步任务 + DISPATCH_QUEUE_CONCURRENT 并行队列,会开辟多个线程执行,调用 marr 的 addObject: 方法,多个线程抢占同一个资源,会 crash。

4.下列代码的运行结果

- (void)viewDidLoad {    [super viewDidLoad];    NSLog(@"1");    dispatch_sync(dispatch_get_main_queue(), ^{        NSLog(@"2");    });    NSLog(@"3"); }

答案:输出 1 后发生死锁,主线程卡死。
原因:同步任务会阻塞当前线程,然后把 Block 中的任务放到指定的队列中执行,只有等到 Block 中的任务完成后才会让当前线程继续往下运行。那么这里的步骤就是:打印完第一句后,dispatch_sync 立即阻塞当前的主线程,然后把 Block 中的任务放到 main_queue 中,将 main_queue 中的任务会被取出来放到主线程中执行,但主线程这个时候已经被阻塞了,所以 Block 中的任务就不能完成,它不完成,dispatch_sync 就会一直阻塞主线程,这就是死锁现象。导致主线程一直卡死。

5.下面代码的运行结果

dispatch_queue_t queue = dispatch_get_global_queue(0, 0); dispatch_async(queue, ^{     NSLog(@"1");     dispatch_sync(queue, ^{         NSLog(@"2");     });     NSLog(@"3"); }); NSLog(@"4");

答案:4 -> 1 -> 2 -> 3
原因:dispatch_sync 为同步任务,在dispatch_get_global_queue中执行,所以3会在4的前面执行。

6.下面代码的运行结果

dispatch_queue_t queue = dispatch_queue_create("com.xxx.xxx", DISPATCH_QUEUE_SERIAL); dispatch_async(queue, ^{     NSLog(@"1");     dispatch_sync(queue, ^{         NSLog(@"2");     });     NSLog(@"3"); }); NSLog(@"4");

答案:会打印 “之前”、“之后” 和 “sync 之前”,然后死锁。
原因:DISPATCH_QUEUE_SERIAL 创建了串行队列。由于 dispatch_async 是异步任务,则不阻塞当前线程,“之前”、“之后”会被执行。同时其中的“sync 之前”也会被执行。然后 dispatch_sync 是同步执行,于是它所在的线程会被阻塞,一直等到 sync 里的任务执行完才会继续往下。于是 sync 就把自己 Block 中的任务放到 queue 中,但是 queue 是一个串行队列,一次执行一个任务,所以 sync 的 block 必须等到前一个任务执行完毕,可万万没想到的是 queue 正在执行的任务就是被 sync 阻塞了的那个。于是又发生了死锁。所以 sync 所在的线程被卡死了。剩下的两句代码自然不会打印。

7.下面代码的运行结果。把 0 换成 1 或者 2 后是什么结果?

dispatch_semaphore_t t1 = dispatch_semaphore_create(0);  dispatch_async(dispatch_get_global_queue(0, 0), ^{     NSLog(@"1");     dispatch_semaphore_signal(t1); }); dispatch_semaphore_wait(t1, DISPATCH_TIME_FOREVER);  dispatch_async(dispatch_get_global_queue(0, 0), ^{     NSLog(@"2");     sleep(2);     dispatch_semaphore_signal(t1); }); dispatch_semaphore_wait(t1, DISPATCH_TIME_FOREVER);  dispatch_async(dispatch_get_global_queue(0, 0), ^{     NSLog(@"3");     dispatch_semaphore_signal(t1); });

答案:1 -> 2 -> 3 顺序打印
原因:将最大并发数量设置为 0 后,就成了串行队列,按顺序执行。

将 0 修改为 1 和 2 后,顺序就不一定了,因为多个异步任务可以同时执行。

8.下面代码的运行结果? 将 performSelector: 换成 performSelectorOnMainThread: 呢?

- (void)viewDidLoad {     [super viewDidLoad];      dispatch_async(dispatch_get_global_queue(0, 0), ^{         NSLog(@"1");          [self performSelector:@selector(test) withObject:nil afterDelay:0];          NSLog(@"3");     }); }

答案:输出 1 3,不会输出 2
原因:performSelecter: 在子线程是不起作用的,因为子线程默认没有 Runloop,也就没有 Timer。而 performSelecter: 的原理是内部会创建一个 Timer 并添加到当前线程的 RunLoop 中。所以如果当前线程没有 RunLoop,则这个方法会失效。解决办法是采用 GCD timer。参考

performSelector: 换成 performSelectorOnMainThread:的结果:

- (void)viewDidLoad {     [super viewDidLoad];      dispatch_async(dispatch_get_global_queue(0, 0), ^{         NSLog(@"1");          [self performSelectorOnMainThread:@selector(test) withObject:nil waitUntilDone:YES];          NSLog(@"3");     }); }  - (void)test {     NSLog(@"2"); }

答案:输出 1 2 3
原因:该方法回强制回主线程,设置 waitUntilDone 参数为 YES,则表示等待主线程任务执行完成之后再回来执行。如果设置为 NO,则输出 1 3 2。

9.下面代码的运行结果?

dispatch_async(dispatch_get_main_queue(), ^{     NSLog(@"1, thrad: %@", [NSThread currentThread]); });  dispatch_async(dispatch_get_main_queue(), ^{     NSLog(@"2, thrad: %@", [NSThread currentThread]); });  dispatch_async(dispatch_get_main_queue(), ^{     NSLog(@"3, thrad: %@", [NSThread currentThread]); });

答案:1 2 3 并且线程都是主线程。
原因:主队列是串行队列,放在串行队列中的任务不会开辟新的线程执行。

10. 有一个 generateContent 比较耗时的方法,会生成特定的内容返回,现在需要调用这个方法:1. 如果方法立马返回,则立即返回这内容 2. 如果 3s 未返回,则返回为空。如何实现?

可以使用信号量 dispatch_semaphore_tdispatch_queue_t 实现:

信号量 dispatch_semaphore_t实现

dispatch_async 异步调用 generateContent 方法,方法执行完成后进行信号量 singal ,信号量 dispatch_semaphore_t wait 时候可以设置超时时间为 3s即可:

“`objc

  • (NSString *)getSomeContent {
    __block NSString *str;
    dispatch_semaphore_t sempahore = dispatch_semaphore_create(0);
    dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
    dispatch_async(queue, ^{ // 异步调用
    str = [self generateContent]; // 可能的耗时操作
    dispatch_semaphore_signal(sempahore);
    });

    dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3 * NSEC_PER_SEC); // 设置 3s 超时
    dispatch_semaphore_wait(sempahore, time);

    return str;
    }

  • (NSString *)generateContent {
    sleep(5); // 模拟耗时操作

部分转自互联网,侵权删除联系

赞(0) 打赏
部分文章转自网络,侵权联系删除b2bchain区块链学习技术社区 » iOS面试题目解析19 – GCD题目求职学习资料
分享到: 更多 (0)

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

b2b链

联系我们联系我们