标签:
GCD通过任务和队列实现多线程功能
同步
同步执行任务的函数
void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block),Block类型
void dispatch_sync_f(dispatch_queue_t queue, void *context, dispatch_function_t work),函数类型(每个Block类型都对应一个函数类型)
同步执行任务的其他函数(barrier),在前面的任务执行完毕它才执行,它后边的任务等它执行完毕才执行
void dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t block),block类型
dispatch_barrier_sync_f(dispatch_queue_t queue, void *context, dispatch_function_t work),函数类型
异步
异步执行任务的函数(参数意义与同步函数相同)
异步执行任务的其他函数(barrier),在前面的任务执行完毕它才执行,它后边的任务等它执行完毕才执行(参数意义与同步函数相同)
并发队列
串行队列
队列的种类
串行队列
dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr)
并发队列
dispatch_queue_t dispatch_queue_create(const char *label, dispatch_queue_attr_t attr)
主队列(串行,只能在主线程中运行)
全局队列(并发)
同步函数
同步函数主队列
/**
- 运行在主线程主队列(未开启新的线程),主线程被卡死
- 原因:任务代码等待着当前函数执行完毕才能执行(当前函数正在执行且未执行完毕);
当前函数等待着任务代码 执行完毕才能执行(当前任务正在执行且未执行完毕);
相互等待,出现死锁
*/
//获取主队列
dispatch_queue_t queue = dispatch_get_main_queue();
//添加任务到队列
dispatch_sync(queue, ^{
//任务1代码
});
dispatch_sync(queue, ^{
//任务2代码
});
同步函数串行队列
/**
- 运行在主线程串行非主队列(未开启新的线程),任务串行执行
*/
//创建串行队列
dispatch_queue_t queue = dispatch_queue_create("com.23565@qq", DISPATCH_QUEUE_SERIAL);
//添加任务到队列
dispatch_sync(queue, ^{
//任务1代码
});
dispatch_sync(queue, ^{
//任务2代码
});
同步函数并发队列
/**
- 运行在非主线程并发队列(未开启新的线程),任务串行执行
*/
//获取全局队列(并发)
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//将任务加至队列
dispatch_sync(queue, ^{
//任务1代码
});
dispatch_sync(queue, ^{
//任务2代码
});
异步函数
异步函数主队列
/**
- 运行在主线程主队列(未开启新的线程),任务串行执行
*/
// 获得主队列
dispatch_queue_t queue = dispatch_get_main_queue();
// 将任务加入队列
dispatch_async(queue, ^{
//任务1代码
});
dispatch_async(queue, ^{
//任务2代码
});
异步函数串行队列
/**
- 运行在主函数串行非主队列(未开启新的线程),任务串行执行
*/
//创建串行队列
dispatch_queue_t queue = dispatch_queue_create("com.23565@qq", DISPATCH_QUEUE_SERIAL);
//将任务加至队列
dispatch_async(queue, ^{
//任务1代码
})
dispatch_async(queue, ^{
//任务2代码
})
异步函数并发队列
/**
- 运行在非主线程并发队列(开启新的线程),任务并发执行
- 系统根据任务创建线程(无法确定任务执行在哪个线程)
*/
//获得全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//将任务加入队列
dispatch_async(queue, ^{
//任务1代码
});
dispatch_async(queue, ^{
//任务2代码
});
从主线程到子线程
注意
实现代码
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//需要在子线程中执行的任务代码
})
从子线程到主线程
注意
实现代码
dispatch_async(dispatch_get_main_queue(), ^{
//需要在主线程中执行的代码
})
单次执行(通常用在单例模式的设计中)
//定义一个标记
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//此处的代码只会被执行一次
});
延迟执行
/**
- 方法一(GCD)
*/
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//此处的代码将延迟执行
});
/**
- 方法二(performSelector)
*/
[self performSelector:@selector(run) withObject:self afterDelay:2.0];
/**
- 方法三(NSTimer)
*/
[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(run) userInfo:nil repeats:NO]
快速迭代
void dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t))
/**
iterations:迭代执行的次数
queue:任务队列
block:迭代执行的代码
size_t:用来定义当前迭代到第几次,需要自己添加,如在size_t后添加index索引,记录当前的迭代次数
*/
Barrier
/**
- Barrier中的任务,只能在它前面的任务执行完毕才能执行
Barrier后的任务,只能等到它执行完毕才能执行
- 要将队列添加到自己创建的并发队列中,否其功能等同于函数
void dispatch_async(dispatch_queue_t queue, dispatch_block_t block)
*/
//创建队列(通常是自己创建的并发队列)
dispatch_queue_t queue = dispatch_queue_create("123", DISPATCH_QUEUE_CONCURRENT);
//将任务添加到队列
dispatch_async(queue, ^{
//在Barrier前执行的任务代码
});
dispatch_barrier_async(queue, ^{
//Barrier中的任务代码
});
dispatch_async(queue, ^{
//在Barrier后执行的任务代码
});
队列组
//获取全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//创建队列组
dispatch_group_t group = dispatch_group_create();
//添加任务到队列组
dispatch_group_async(group, queue, ^{
//任务1代码
});
dispatch_group_async(group, queue, ^{
//任务2代码
});
dispatch_group_notify(group, queue, ^{
//任务3代码
/**
group组中的所有任务执行完毕在执行
若group为空,则立即执行
*/
});
实现原理
实现代码
//获得队列
dispatch_queue_t queue = dispatch_get_main_queue();
//创建一个定时器
self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
//设置定时器的各种属性(起止时间)
dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(8.0 * NSEC_PER_SEC));
uint64_t interval = (uint64_t)(1.0 * NSEC_PER_SEC);
//设置
dispatch_source_set_timer(self.timer, start, interval, 0);
//设置回调
dispatch_source_set_event_handler(self.timer, ^{
//定时器被触发时所要执行的代码
});
//开启定时器
dispatch_resume(self.timer);
//取消定时器
dispatch_cancel(self.timer);
标签:
原文地址:http://www.cnblogs.com/funny11/p/4961833.html