面试题答案
一键面试GCD并发队列常见创建方式及任务提交示例
- 使用
dispatch_get_global_queue
获取全局并发队列- 该函数用于获取系统提供的全局并发队列。其函数原型为:
dispatch_queue_t dispatch_get_global_queue(dispatch_queue_priority_t priority, unsigned long flags);
priority
参数指定队列优先级,常见的有DISPATCH_QUEUE_PRIORITY_HIGH
(高优先级)、DISPATCH_QUEUE_PRIORITY_DEFAULT
(默认优先级)、DISPATCH_QUEUE_PRIORITY_LOW
(低优先级)和DISPATCH_QUEUE_PRIORITY_BACKGROUND
(后台优先级)。flags
参数目前一般设为0。- 示例代码:
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(globalQueue, ^{ // 这里是要执行的任务 NSLog(@"执行任务在全局并发队列中"); });
- 使用
dispatch_queue_create
创建自定义并发队列- 函数原型为:
dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);
label
是队列的标识符,一般使用反向域名形式,如com.example.myqueue
。attr
用于设置队列属性,若要创建并发队列,可传入DISPATCH_QUEUE_CONCURRENT
。- 示例代码:
dispatch_queue_t customConcurrentQueue = dispatch_queue_create("com.example.concurrentQueue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(customConcurrentQueue, ^{ NSLog(@"执行任务在自定义并发队列中"); });
并发队列与串行队列在任务执行上的主要区别
- 执行顺序
- 串行队列:任务按照提交的顺序依次执行。一个任务执行完成后,才会开始执行下一个任务。例如:
输出结果一定是先打印“任务1在串行队列中执行”,再打印“任务2在串行队列中执行”。dispatch_queue_t serialQueue = dispatch_queue_create("com.example.serialQueue", DISPATCH_QUEUE_SERIAL); dispatch_async(serialQueue, ^{ NSLog(@"任务1在串行队列中执行"); }); dispatch_async(serialQueue, ^{ NSLog(@"任务2在串行队列中执行"); });
- 并发队列:任务不一定按照提交的顺序执行。系统会根据可用的资源和任务优先级等因素,同时调度多个任务并发执行。例如:
输出结果可能是先打印“任务A在并发队列中执行”,也可能是先打印“任务B在并发队列中执行”,或者两个任务几乎同时打印。dispatch_queue_t concurrentQueue = dispatch_queue_create("com.example.concurrentQueue", DISPATCH_QUEUE_CONCURRENT); dispatch_async(concurrentQueue, ^{ NSLog(@"任务A在并发队列中执行"); }); dispatch_async(concurrentQueue, ^{ NSLog(@"任务B在并发队列中执行"); });
- 执行效率
- 串行队列:由于任务依次执行,在处理一些需要顺序执行的操作(如文件写入,避免数据竞争)时较为合适,但整体执行效率在处理多个独立任务时相对较低,因为不能充分利用多核CPU资源。
- 并发队列:能够充分利用多核CPU资源,在处理多个独立的耗时任务时,执行效率较高。但在处理一些对顺序敏感或者涉及共享资源访问的任务时,需要额外注意同步和数据竞争问题,以确保程序的正确性。