iOS GCD原理详解:核心机制与工作流程
前言
在iOS开发中,Grand Central Dispatch(GCD)是处理多线程编程的核心技术。作为Apple提供的底层C语言API,GCD以其高效、简洁的特点成为iOS开发者必须掌握的技能。本文将深入剖析GCD的核心机制与工作流程,帮助开发者更好地理解和运用这一强大工具。
GCD基础概念
什么是GCD
Grand Central Dispatch(GCD)是Apple开发的多线程编程解决方案,它通过将任务提交到队列中,由系统自动管理线程的生命周期,从而简化了多线程编程的复杂性。
GCD的核心优势
- 自动线程管理:无需手动创建和管理线程
- 高效的任务调度:系统级优化,性能卓越
- 简洁的API:基于Block的编程模型,代码简洁易懂
- 内存安全:避免传统多线程编程中的竞态条件
GCD核心组件详解
1. 队列(Dispatch Queue)
串行队列(Serial Queue)
串行队列按照先进先出(FIFO)的顺序执行任务,一次只能执行一个任务。
// 创建串行队列
dispatch_queue_t serialQueue = dispatch_queue_create("com.example.serial", DISPATCH_QUEUE_SERIAL);
// 提交任务到串行队列
dispatch_async(serialQueue, ^{
NSLog(@"任务1开始");
[NSThread sleepForTimeInterval:1.0];
NSLog(@"任务1完成");
});
dispatch_async(serialQueue, ^{
NSLog(@"任务2开始");
[NSThread sleepForTimeInterval:1.0];
NSLog(@"任务2完成");
});并发队列(Concurrent Queue)
并发队列可以同时执行多个任务,但任务的完成顺序不确定。
// 创建并发队列
dispatch_queue_t concurrentQueue = dispatch_queue_create("com.example.concurrent", DISPATCH_QUEUE_CONCURRENT);
// 提交任务到并发队列
dispatch_async(concurrentQueue, ^{
NSLog(@"并发任务1");
});
dispatch_async(concurrentQueue, ^{
NSLog(@"并发任务2");
});2. 全局队列(Global Queue)
系统提供的全局并发队列,分为不同的优先级:
// 获取不同优先级的全局队列
dispatch_queue_t highQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_queue_t defaultQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t lowQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);3. 主队列(Main Queue)
主队列是串行队列,专门用于在主线程上执行任务,通常用于UI更新:
// 获取主队列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
// 在主队列中更新UI
dispatch_async(mainQueue, ^{
self.label.text = @"更新UI";
});GCD任务执行方式
同步执行(dispatch_sync)
同步执行会阻塞当前线程,直到任务完成:
dispatch_sync(queue, ^{
// 任务代码
NSLog(@"同步任务执行");
});
// 这里的代码会在上面的任务完成后才执行⚠️ 注意:在主线程中同步执行主队列任务会导致死锁!
异步执行(dispatch_async)
异步执行不会阻塞当前线程,任务会在后台执行:
dispatch_async(queue, ^{
// 任务代码
NSLog(@"异步任务执行");
});
// 这里的代码会立即执行,不会等待上面的任务完成GCD高级特性
1. 延迟执行(dispatch_after)
// 延迟2秒执行
dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC));
dispatch_after(delayTime, dispatch_get_main_queue(), ^{
NSLog(@"延迟执行的任务");
});2. 一次性执行(dispatch_once)
确保代码只执行一次,常用于单例模式:
+ (instancetype)sharedInstance {
static MyClass *instance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
instance = [[MyClass alloc] init];
});
return instance;
}3. 组队列(Dispatch Group)
用于监控一组任务的完成状态:
dispatch_group_t group = dispatch_group_create();
// 添加任务到组
dispatch_group_async(group, queue, ^{
NSLog(@"任务1");
});
dispatch_group_async(group, queue, ^{
NSLog(@"任务2");
});
// 所有任务完成后执行
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"所有任务完成");
});4. 信号量(Dispatch Semaphore)
控制并发访问资源的数量:
// 创建信号量,允许3个并发
dispatch_semaphore_t semaphore = dispatch_semaphore_create(3);
for (int i = 0; i < 10; i++) {
dispatch_async(queue, ^{
// 等待信号量
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"执行任务 %d", i);
[NSThread sleepForTimeInterval:1.0];
// 释放信号量
dispatch_semaphore_signal(semaphore);
});
}