-
全局队列同步执行任务
// 全局队列,负责调度任务
dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
// 任务,使用 block 来包装任务,block 没有参数,没有返回值
void (^task)() = ^ {
};
// 指定执行任务的函数,不会开启线程,就在当前线程执行 block
dispatch_sync(globalQueue, task);
-
全局队列异步执行任务
// 全局队列,负责调度任务
dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
// 任务,使用 block 来包装任务,block 没有参数,没有返回值
void (^task)() = ^ {
};
// 指定执行任务的函数,会开启线程,在其他线程执行 block
dispatch_async(globalQueue, task);
-
创建 dispatch_async 线程
dispatch_async(dispatch_get_global_queue(0, 0), ^{
// 耗时的操作 Code
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageUrlPath]];
UIImage *image = [[UIImage alloc] initWithData:data];
dispatch_async(dispatch_get_main_queue(), ^{
// 更新界面,刷新主线程 Code
self.imageView.image = image;
});
});
-
顺序操作
// myQueue 不能使用全局的对列
dispatch_queue_t myQueue = dispatch_queue_create("qq", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(myQueue, ^{
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageUrlPath]];
_backImage = [[UIImage alloc] initWithData:data];
});
dispatch_async(myQueue, ^{
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:iconImageUrlPath]];
_iconImage = [[UIImage alloc] initWithData:data];
});
dispatch_barrier_async(myQueue, ^{
dispatch_async(dispatch_get_main_queue(), ^{
self.iconImageView.image = _iconImage;
});
});
dispatch_async(myQueue, ^{
dispatch_async(dispatch_get_main_queue(), ^{
self.imageView.image = _backImage;
});
});
-
群组操作,线程通知
// queue 负责调度任务
dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
// group 负责监控任务
dispatch_group_t group = dispatch_group_create();
// 第一个任务
dispatch_group_async(group, globalQueue, ^{
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageUrlPath]];
_backImage = [[UIImage alloc] initWithData:data];
});
// 第二个任务
dispatch_group_async(group, globalQueue, ^{
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:iconImageUrlPath]];
_iconImage = [[UIImage alloc] initWithData:data];
});
// 其它所有添加的任务都执行完后,再执行该任务,但该任务需最后添加
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
self.imageView.image = _backImage;
self.iconImageView.image = _iconImage;
});
-
群组操作实现原理
/*
The dispatch_group_async() convenience function behaves like so:
void
dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, dispatch_block_t block)
{
dispatch_retain(group);
dispatch_group_enter(group);
dispatch_async(queue, ^{
block();
dispatch_group_leave(group);
dispatch_release(group);
});
}
*/
// queue 负责调度任务
dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
// group 负责监控任务
dispatch_group_t group = dispatch_group_create();
// 入组,之后的 block 会被 group 监听
dispatch_group_enter(group);
dispatch_async(globalQueue, ^{
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:imageUrlPath]];
_backImage = [[UIImage alloc] initWithData:data];
// 出组,block 的末尾,所有任务执行完毕后,添加一个出组,dispatch_group_enter & dispatch_group_leave 必须成对出现
dispatch_group_leave(group);
});
// 入组,之后的 block 会被 group 监听
dispatch_group_enter(group);
dispatch_async(globalQueue, ^{
NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:iconImageUrlPath]];
_iconImage = [[UIImage alloc] initWithData:data];
// 出组,block 的末尾,所有任务执行完毕后,添加一个出组,dispatch_group_enter & dispatch_group_leave 必须成对出现
dispatch_group_leave(group);
});
// 阻塞式等待调度组中所有任务执行完毕
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
// 群组结束
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
self.imageView.image = _backImage;
self.iconImageView.image = _iconImage;
});
-
延迟操作
// 从现在开始 n 纳秒后,1.0 * NSEC_PER_SEC = 1 秒
dispatch_time_t when = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC));
// 延迟指定时间(纳秒)后在指定的队列中调度执行,异步执行
dispatch_after(when, dispatch_get_global_queue(0, 0), ^{
NSLog(@"%@", [NSThread currentThread]);
});
-
循环操作
// 循环执行设定的次数(5 次),同步执行
dispatch_apply(5, dispatch_get_global_queue(0, 0), ^(size_t index) {
NSLog(@"dispatch_apply: %zu --- %@", index, [NSThread currentThread]);
});
-
一次性操作
/*
有的时候,在程序开发中,有些代码只想从程序启动就只执行一次,典型的应用场景就是 “单例”。
dispatch_once 能够保证 block 中的代码,只会被执行一次,onceToken == 0 时就会执行 block 的代码,执行后 变为 -1,
dispatch 内部也有一把锁,是能够保证 "线程安全" 的,而且是苹果公司推荐使用的。
block 同步执行,能够保证后续的代码直接使用 block 执行后的结果。
*/
// 同步执行
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
});
-
同步任务的作用
// 同步任务,可以让其他异步执行的任务,"依赖" 某一个同步任务。例如:在用户登录之后,再异步下载文件。
// 队列
dispatch_queue_t q = dispatch_queue_create("qq", DISPATCH_QUEUE_CONCURRENT);
// 异步执行 task
dispatch_async(q, ^{
dispatch_sync(q, ^{
NSLog(@"Login %@", [NSThread currentThread]);
});
dispatch_async(q, ^{
NSLog(@"Download A %@", [NSThread currentThread]);
});
dispatch_async(q, ^{
NSLog(@"Download B %@", [NSThread currentThread]);
});
});
-
主队列同步任务不死锁
// 主线程中主队列同步执行时,主队列和主线程相互等待会造成死锁。在子线程中执行不会死锁。
// 并发队列
dispatch_queue_t q = dispatch_queue_create("qq", DISPATCH_QUEUE_CONCURRENT);
// 任务
void (^task)() = ^ {
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(@"come here %@", [NSThread currentThread]);
});
};
// 异步执行任务
dispatch_async(q, task);