GCD特点
- 简单易用:通过提供
dispatch_queue_t
队列和一些简单的函数,如dispatch_async
、dispatch_sync
,开发者能轻松将任务提交到队列执行,无需像传统线程那样管理线程生命周期。例如:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
// 这里执行异步任务
NSLog(@"异步任务在后台线程执行");
});
- 基于队列:有主队列、全局队列和自定义队列。主队列与主线程关联,在主线程执行任务;全局队列是系统提供的并行队列。自定义队列可控制任务执行顺序和并发行为。
- 自动管理线程:GCD自动管理线程的创建、调度和销毁,开发者只需关注任务逻辑,无需手动管理线程池。
GCD适用场景
- 异步任务:网络请求、文件读写等耗时操作。如网络请求:
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://example.com"]];
dispatch_async(dispatch_get_main_queue(), ^{
// 更新UI
UIImage *image = [UIImage imageWithData:data];
self.imageView.image = image;
});
});
- 并行计算:对数组元素进行并行处理等。
NSOperationQueue特点
- 面向对象:基于
NSOperation
和NSOperationQueue
类,NSOperation
是抽象类,常用子类有NSInvocationOperation
和NSBlockOperation
,可将任务封装为对象。例如:
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
// 任务逻辑
NSLog(@"NSBlockOperation任务执行");
}];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperation:operation];
- 任务依赖管理:可设置任务之间的依赖关系,确保任务按特定顺序执行。如:
NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"操作1执行");
}];
NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"操作2执行");
}];
[operation2 addDependency:operation1];
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperations:@[operation1, operation2] waitUntilFinished:NO];
- 可配置性强:能设置最大并发数等属性,控制队列执行行为。
NSOperationQueue适用场景
- 复杂任务调度:需要管理任务依赖和执行顺序的场景,如一个任务依赖另一个任务的执行结果。
- 灵活控制:需要动态添加、移除操作,或根据运行时情况调整队列属性时。
避免资源竞争和死锁问题
- 使用队列同步:在GCD中,使用
dispatch_sync
或dispatch_barrier_async
等函数。例如,多个任务读写同一数据时,使用dispatch_barrier_async
:
dispatch_queue_t queue = dispatch_queue_create("com.example.syncQueue", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
// 读操作
});
dispatch_barrier_async(queue, ^{
// 写操作
});
dispatch_async(queue, ^{
// 读操作
});
- 锁机制:使用
NSLock
、NSRecursiveLock
等。在NSOperationQueue中:
NSLock *lock = [[NSLock alloc] init];
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
[lock lock];
// 访问共享资源
[lock unlock];
}];
- 避免循环依赖:在设置NSOperation任务依赖时,确保不存在循环依赖,否则会导致死锁。如上述设置依赖示例,合理规划任务顺序避免出现A依赖B,B又依赖A的情况。