1.GCD
- 同步/异步和串行/并发
- dispatch_barrier_async
- dispatch_group
(1)同步/异步和串行/并发
- dispatch_sync(serial_queue, ^{//任务});
- dispatch_async(serial_queue,^{//任务});
- dispatch_sync(concurrent_queue,^{//任务});
- dispatch_async(concurrent_queue,^{//任务});
同步串行
上面代码会产生- (void)viewDidLoad { [super viewDidLoad]; dispatch_sync(dispatch_get_main_queue(), ^{ [self doSomething]; }); }
死锁
,产生死锁的原因是,队列引起的循环等待。
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_sync(serialQueue, ^{
[self doSomething];
});
}
上面的代码是没有问题的
同步并发
- (void)viewDidLoad {
NSLog(@"1");
dispatch_sync(global_queue(), ^{
NSLog(@"2");
dispatch_sync(global_queue(), ^{
NSLog(@"3");
});
NSLog(@"4");
});
NSLog(@"5");
}
打印结果:12345
异步串行
- (void)viewDidLoad {
[super viewDidLoad];
dispatch_async(dispatch_get_main_queue(), ^{
[self doSomething];
});
}
异步并发
- (void)viewDidLoad {
dispatch_async(global_queue,^{
NSLog(@"1");
[self performSelector:@selector(printLog)
withObject:nil
afterDelay:0];
NSLog(@"3");
})
}
- (void)printLog {
NSLog(@"2");
}
打印结果: 13
2.dispatch_barrier_async()
(1)怎样利用GCD实现多读单写?
dispatch_barrier_async(concurrent_queue,^{//写操作});
#import <Foundation/Foundation.h>
@interface UserCenter : NSObject
- (id)objectForKey:(NSString *)key;
- (void)setObject:(id)obj forKey:(NSString *)key;
@end
#import "UserCenter.h"
@interface UserCenter()
{
dispatch_queue_t concurrent_queue;
NSMutableDictionary *userCenterDic;
}
@end
@implementation UserCenter
- (instancetype)init{
self = [super init];
if (self) {
// 通过宏定义DISPATCH_QUEUE_CONCURRENT 创建一个并发队列
concurrent_queue = dispatch_queue_create("read_write_queue", DISPATCH_QUEUE_CONCURRENT);
// 创建数据库容器
userCenterDic = [NSMutableDictionary dictionary];
}
return self;
}
- (id)objectForKey:(NSString *)key{
__block id obj;
//同步读取指定数据
dispatch_sync(concurrent_queue, ^{
obj = [userCenterDic objectForKey:key];
});
return obj;
}
- (void)setObject:(id)obj forKey:(NSString *)key{
// 异步栅栏调用设置数据
dispatch_barrier_async(concurrent_queue, ^{
[userCenterDic setObject:obj forKey:key];
});
}
@end
3.dispatch_group_async()
使用GCD实现这个需求:A、B、C三个任务并发,完成后执行任务D?
#import <Foundation/Foundation.h>
@interface GroupObject : NSObject
- (void)handle;
@end
#import "GroupObject.h"
@interface GroupObject()
{
dispatch_queue_t concurrent_queue;
NSMutableArray <NSURL *> *arrayURLs;
}
@end
@implementation GroupObject
- (instancetype)init
{
self = [super init];
if (self) {
//创建并发队列
concurrent_queue = dispatch_queue_create("concurrent_queue",DISPATCH_QUEUE_CONCURRENT);
arrayURLs = [NSMutableArray array];
}
return self;
}
- (void)handle{
//创建一个group
dispatch_group_t group = dispatch_group_create();
// for循环遍历各个元素
for (NSURL *url in arrayURLs) {
//异步组分派到并发队列当中
dispatch_group_async(group, concurrent_queue, ^{
//根据url去下载图片
NSLog(@"%@",url);
});
}
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
//当添加到数组中的所有任务执行完成之后会调用该block
NSLog(@"所有图片下载完成");
});
}
@end
4.NSOperation
需要和NSOperationQueue配合使用来实现多线程方案
- 添加任务依赖
- 任务执行状态控制
- 最大并发量
(1)任务执行状态控制
- isReady 当前任务是否处于就绪状态
- isExecuting 当前任务是否处于执行中的状态
- isFinished 当前任务是否已经执行完成
- isCancelled 当前任务是否已取消
如果只重写main方法,底层控制变更任务执行状态,以及任务退出。
如果重写了start方法,自行控制任务状态。