博客> GCD的用法
GCD的用法
2017-12-11 14:06 评论:0 阅读:89 进击的可乐SAMA


一、GCD的基本用法
1.异步函数家并发队列(具备开启其他线程的能力,线程同时处理任务)


//创建并发队列
dispatch_queue_t queue = dispathc_queue_create("111", DISPATCH_QUEUE_CONCURRENT);
/*
第一个参数:队列的名字
第二个参数:队列的类型
*/

//GCD默认已经提供了全局的并发队列,供整个应用使用,可以无需手动创建
dispatch_queue_t queue = dispathch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
/*
第一个参数:优先级
第二个参数:暂时无用
*/

//用异步的方式执行任务(可以在新的线程中执行任务,具备开启新线程的能力)
dispatch_async(queue, ^{
    //执行任务的内容
});


2.同步函数并发队列(不具备开启其他线程的能力,不能并发执行任务)


//使用全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//用同步的方式执行任务(只能在当前线程中执行任务,不具备开启新线程的能力)
dispatch_sync(queue, ^{
    //任务内容
});


3.异步函数加串行队列(只开一条线程)


//创建串行队列
dispatch_queue_t queue = dispatch_queue_create("111", DISPATCH_QUEUE_SERIAL);

//用异步的方式执行任务
dispatch_async(queue, ^{
    //任务内容
});


4.同步函数加串行队列(不开线程)


//创建串行队列
dispatch_queue_t queue = dispatch_queue_create("111", DISPATCH_QUEUE_SERIAL);

//以同步的方式执行任务
dispatch_sync(queue, ^{
    //任务内容
});


5.主队列执行任务


//获取主队列(使用主队列,不论是同步还是异步,都会在主线程中执行)
dispatch_queue_t queue = dispatch_get_main_queue();
//注:如果用主队列,再使用同步函数,会发生阻塞

dispatch_async(queue, ^{
    //任务内容
});


二、线程之间的通讯(回到主线程)


//使用异步方式回到主线程
dispatch_async(dispatch_get_main_queue(), ^{
    //任务内容
});


三、GCD的常用函数
1.栅栏的用法


//创建并发队列
dispatch_queue_t queue = dispatch_queue_create("111", DISPATCH_QUEUE_CONCURRENT);

dispatch_async(queue, ^{
    NSLog(@"11111");
});

dispatch_async(queue, ^{
    NSLog(@"22222");
});

//在barrier前面的任务会先执行,等待前面任务执行完毕后,再执行barrier中的任务,最后执行barrier之后的任务(如果让barrier执行有效果,queue不能使全局并发队列)
dispatch_barrier_async(queue, ^{
    NSLog(@"33333");
});

dispatch_async(queue, ^{
    NSLog(@"44444");
});

dispatch_async(queue, ^{
    NSLog(@"55555");
});


2.延时执行


//NSObjet方法,方法延迟N秒后执行
[self performSelector:@selector(方法名) withObject:参数 afterDelay:延迟时间];

//GCD延迟方法
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int_64_t)(延迟时间 * NSEC_PER_SEC)),         dispatch_get_main_queue(), ^{
    //任务内容
});

//NSTimer延迟方法
[NSTimer scheduledTimerWithTimeInterval:延迟时间 target:self selector:@selector(方法名) userInfo:参数 repeats:NO];


3.只加载一次的代码


//其中的代码整个程序只会加载一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
    //只运行一次的代码
});


4.快速遍历(同时遍历,节约时间,但是没有顺序)


dispatch_apply(遍历次数, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index) {
    //要遍历的内容
});


5.队列组的用法


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, ^{
    NSLog(@"11111");
});

dispatch_group_async(group, queue, ^{
    NSLog(@"22222");
});

//当上述方法运行完毕以后才会运行notify方法
dispatch_group_notify(group, queue, ^{
    NSLog(@"33333");
});


6.信号量的用法(使用信号量可以保证notify最后执行)


//队列组
dispatch_group_t group = dispatch_group_create();

//全局并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//信号量
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

dispatch_group_async(group, queue, ^{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)),                   dispatch_get_main_queue(), ^{
        NSLog(@"111111111111");

        //使计数加一
        dispatch_semaphore_signal(semaphore);
    });
});

dispatch_group_async(group, queue, ^{
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)),         dispatch_get_main_queue(), ^{
        NSLog(@"222222222");
        dispatch_semaphore_signal(semaphore);
    });
});

dispatch_group_notify(group, queue, ^{
    //让计数减成0
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    NSLog(@"333333");
});


四、完整单粒模式写法
 单粒模式.png

收藏
0
sina weixin mail 回到顶部