GCD概念:Grand Central Dispatch
1.queue 队列 dispatch queue 分发队列
2.task 任务
3.thread 线程
task 是一个一个单独的任务(方法,函数,block)
queue里存放的是一个或者多个task
thread 为了保证task能顺利执行,queue会开辟适当的thread,在开辟的thread里面执行task
queue分两种:
1.serialqueue(串行队列)
特点:任务先进先出.排在前面任务先执行,执行之后后面的任务才开始执行
2.concurrentQueue(并行队列)
特点:任务先进先出,排在前面的任务先执行,一旦开始,后面的任务就开始执行(无需等待一个任务的结束)
把任务放到什么样的队列里,任务就遵循这个队列的规则
//serialqueue
- (IBAction)click1:(UIButton *)sender {
//如果要让任务串行,使用serialqueue
//method1:系统serialqueue(mainqueue单例)
//mainqueue只会为任务(无论多少个任务)开辟一个线程,而且这个线程是主线程
//?? 这些任务在 主线程中执行,不是会卡死主线程吗?为什么系统还提供mainqueue?
//主线程最大的作用是刷新ui,做线程间的通信
// dispatch_queue_t queue = dispatch_get_main_queue();
//添加一个任务
// dispatch_async(queue, ^{
// NSLog(@"任务1是否为主线程:%d,%@",[NSThread isMainThread],[NSThread currentThread]); // 1
// });
//method2:创建一个serialqueue //解决了串行问题和同步的问题
//自己创建的serialQueue也只为任务(不论有几个)创建一个线程,这个线程是子线程,既不会卡死主线程,也实现线程同步
dispatch_queue_t queue = dispatch_queue_create("createa.SerialQueue", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
NSLog(@"任务1是否为主线程:%d,%@",[NSThread isMainThread],[NSThread currentThread]); // 0
});
//凡是使用create的对象都必须释放
dispatch_release(queue);}
//concurrentQueue
- (IBAction)click2:(UIButton *)sender {
//如果要并发执行任务,使用concurrentQueue
//method1:系统的globalQueue(单例) 使用系统的就够了
// dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// dispatch_async(queue, ^{
// NSLog(@"任务1是否为主线程:%d,%@",[NSThread isMainThread],[NSThread currentThread]); // 0
//
// //如果需要刷新界面 dispatch_get_main_queue一般是再刷新界面时使用
// dispatch_queue_t mainQueue = dispatch_get_main_queue();
// dispatch_async(mainQueue, ^{
// NSLog(@"刷新ui");
// });
// });
//method2:创建一个concurrentQueue 不常用
dispatch_queue_t queue = dispatch_queue_create("adddd", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"任务1是否为主线程:%d,%@",[NSThread isMainThread],[NSThread currentThread]); // 0
});
}
//
- (IBAction)click3:(UIButton *)sender {
//
// dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// dispatch_time poptiem = dispatch_time(DISPATCH_TIME_NOW, (int64_t)3 * NSEC_PER_SEC);
//延时执行
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)3 * NSEC_PER_SEC), dispatch_get_main_queue(),^(void){
NSLog(@"delay");
});
}
- (IBAction)click4:(UIButton *)sender {
NSArray *arr = @[@"红楼梦",@"水浒传",@"西游记",@"三国演义"];
//使用CONCURRENT获取的queue为并发的,apply中并发执行数组长度个数的任务,第一个任务开始后,以后的任务也开始执行,输出的结果是无序的
//dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_queue_t queue = dispatch_queue_create("apply", DISPATCH_QUEUE_CONCURRENT);
//重复执行N遍 ^(size_t) index随机的下表
dispatch_apply(4, queue, ^(size_t index) {
// NSLog(@"dispatch_apply");
NSLog(@"%@",arr[index]);//无序的
NSLog(@"asdfas");
});
}
//group
- (IBAction)click5:(UIButton *)sender {
//
dispatch_queue_t queue = dispatch_queue_create("group", DISPATCH_QUEUE_CONCURRENT);
dispatch_group_t group = dispatch_group_create();
//并发执行
dispatch_group_async(group, queue, ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)3 * NSEC_PER_SEC), dispatch_get_main_queue(),^(void){
NSLog(@"group1");
});
});
dispatch_group_async(group, queue, ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)3 * NSEC_PER_SEC), dispatch_get_main_queue(),^(void){
NSLog(@"group5"); });
});
//该group中的调用的方法不管是在那个队列,线程或其他位置,只有等他们全部执行完之后才会执行notify任务
dispatch_group_notify(group, queue, ^{
NSLog(@"already go!");//当该group所有task执行完之后才会执行该方法
});
}
//读写操作同时进行时.数据可能不一样
- (IBAction)click6:(UIButton *)sender {
//
dispatch_queue_t queue = dispatch_queue_create("barrier", DISPATCH_QUEUE_CONCURRENT);
// dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
// dispatch_queue_t queue = dispatch_queue_create("barrier", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"20age");
});
dispatch_async(queue, ^{
NSLog(@"10000");
});
//barrier 之后的task永远在barrier执行之后才能执行(并发)
//也可以使用barrier实现同步执行
dispatch_barrier_async(queue, ^{
NSLog(@"xieru");
});
dispatch_async(queue, ^{
NSLog(@"henan");
});
dispatch_async(queue, ^{
NSLog(@"nan:");
});
dispatch_release(queue);
}
- (IBAction)click7:(UIButton *)sender {
//
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//可以写单例
NSLog(@"once");//只能执行一次
// s = [[Singlton alloc]init];
// return s;
});
}
- (IBAction)click8:(UIButton *)sender {
dispatch_queue_t queue = dispatch_queue_create("syn", DISPATCH_QUEUE_CONCURRENT);
//等block执行完毕后才会执行下面的代码(串行)
dispatch_sync(queue, ^{
for (int i = 0; i<10; i++) {
NSLog(@"%d",i);
}
});
NSLog(@"ok");
dispatch_release(queue);
}
- (IBAction)click9:(UIButton *)sender {
dispatch_queue_t queue = dispatch_queue_create("async_f", DISPATCH_QUEUE_CONCURRENT);
//context可以是任何类型的参数
dispatch_async_f(queue,@"context", fucntion);
dispatch_release(queue);
}