GCD简单使用

开发中有时候可能会有一些很耗时的操作,不可能说让屏幕一直卡着,等操作完成,那体验就很尴尬了。所以多线程还是需要来一来的。

GCD:

并发队列--同步
NSLog(@"---00000--%@",[NSThread currentThread]);
    dispatch_queue_t queue=dispatch_queue_create("aaa", DISPATCH_QUEUE_CONCURRENT);
    dispatch_sync(queue, ^{
        for (int i=0; i<3; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
        
    });
    dispatch_sync(queue, ^{
        for (int i=3; i<6; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    NSLog(@"---aa--%@",[NSThread currentThread]);

看看结果

GCD简单使用_第1张图片
并发队列-同步.png

可以看出没有开启新线程,而且是顺序执行的,需要等待前面的任务完成后才执行后面的任务。同步执行就是一个个来,所以是同步的话,是什么队列,执行顺序没区别。同步和异步决定开不开新线程。

并发队列--异步
NSLog(@"---00000--%@",[NSThread currentThread]);
    dispatch_queue_t queue=dispatch_queue_create("bbb", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        for (int i=0; i<3; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i=3; i<6; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    NSLog(@"---bb--%@",[NSThread currentThread]);

编译结果如下:


GCD简单使用_第2张图片
并发队列-异步.png

并发队列-异步,开启了新的线程,不按顺序执行。编译结果容易让人以为是主线程的打印完再打印新开的线程,但是这里并不是一定先打印完---bb 哦,可以在打印---bb前面先睡一下试试。

串行队列--同步
NSLog(@"---00000--%@",[NSThread currentThread]);
    dispatch_queue_t queue=dispatch_queue_create("cc", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(queue, ^{
        for (int i=0; i<3; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i=3; i<6; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    NSLog(@"---cc--%@",[NSThread currentThread]);

编译结果如下:


GCD简单使用_第3张图片
串行队列-同步.png

这就没什么好说的了,没开新的线程,顺序执行。

串行队列--异步
NSLog(@"---00000--%@",[NSThread currentThread]);
    dispatch_queue_t queue=dispatch_queue_create("dd", DISPATCH_QUEUE_SERIAL);
    dispatch_async(queue, ^{
        for (int i=0; i<3; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i=3; i<6; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    NSLog(@"---dd--%@",[NSThread currentThread]);

编译结果如下:


GCD简单使用_第4张图片
串行队列-异步.png

可以看出队列中的任务是顺序执行的。这里也是一样,并不是一定先打印完---dd 哦,可以在打印---dd前面先睡一下试试。

主队列--同步
NSLog(@"---00000--%@",[NSThread currentThread]);//只打印这句
    dispatch_queue_t queue=dispatch_get_main_queue();
    dispatch_sync(queue, ^{
        for (int i=0; i<3; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    dispatch_sync(queue, ^{
        for (int i=3; i<6; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    NSLog(@"---ee--%@",[NSThread currentThread]);

编译结果如下:


主队列-同步.png

这种情况就死锁了,主线程在等同步任务执行完,而同步任务也在等主线程把这个同步任务执行完,互相等待,死锁了。

主队列--异步
NSLog(@"---h00000--%@",[NSThread currentThread]);
    dispatch_queue_t queue=dispatch_get_main_queue();
    dispatch_async(queue, ^{
        for (int i=0; i<3; i++) {
            NSLog(@"---h%d--%@",i,[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i=3; i<6; i++) {
            NSLog(@"---h%d--%@",i,[NSThread currentThread]);
        }
    });
    NSLog(@"---h ee--%@",[NSThread currentThread]);

编译结果如下:


GCD简单使用_第5张图片
主队列-异步.png

将任务放到主队列,不会马上执行,要等到所有除了我们自己添加到主队列的任务的任务都执行完毕才会执行我们自己添加到主队列的任务。所以---h00000后面一定先打印---h ee 再打印剩下的。

  • 全局队列
    这玩意儿跟并发队列一样就不说了。
队列组
NSLog(@"---hello");
    dispatch_group_t group=dispatch_group_create();
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        for (int i=0; i<3; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        for (int i=3; i<6; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
        for (int i=6; i<9; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
        
    });
    NSLog(@"---end");

编译结果如下:

GCD简单使用_第6张图片
队列组.png

有时候是这种需求,分别执行两个耗时操作,等这两个耗时操作执行完,再做别的操作。如上图,前两个异步执行完,再执行dispatch_group_notify里的任务。

dispatch_group_enter,dispatch_group_leave

这个时候有这样的情况,如果组队列异步操作里也是异步那么dispatch_group_notify会直接响应(可以模仿耗时操作试试)。这个时候就要用dispatch_group_enter,dispatch_group_leave了。

NSLog(@"---hello");
    dispatch_group_t group=dispatch_group_create();
    
    //dispatch_group_enter(group);
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{

        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            [NSThread sleepForTimeInterval:5.0];
            NSLog(@"---h1--%@",[NSThread currentThread]);
            //dispatch_group_leave(group);
        });
    });
    
    //dispatch_group_enter(group);
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
  
        dispatch_async(dispatch_get_global_queue(0, 0), ^{
            [NSThread sleepForTimeInterval:8.0];
            NSLog(@"---h2--%@",[NSThread currentThread]);
        
            //dispatch_group_leave(group);
        });
        
    });
  
    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
            NSLog(@"---h3--%@",[NSThread currentThread]);
        
    });
    NSLog(@"---h end");

编译结果如下:

注释掉dispatch_group_enter 和dispatch_group_leave.png
打开注释后dispatch_group_enter 和dispatch_group_leave.png

这样就能保证先执行前面的异步任务之后再执行dispatch_group_notify里的任务;

dispatch_group_wait --(在group上任务完成前,dispatch_group_wait会阻塞当前线程(所以不能放在主线程调用)一直等待;当group上任务完成,或者等待时间超过设置的超时时间会结束等待;)
NSLog(@"---hello");
    dispatch_group_t group=dispatch_group_create();
    
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        
            NSLog(@"---h1--%@",[NSThread currentThread]);
        });
    
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        
            [NSThread sleepForTimeInterval:8.0];
            NSLog(@"---h2--%@",[NSThread currentThread]);
            
        });
    
    dispatch_group_notify(group, dispatch_get_global_queue(0, 0), ^{
        NSLog(@"---h3--%@",[NSThread currentThread]);
        
    });
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5*NSEC_PER_SEC)));
        NSLog(@"---h4---%@",[NSThread currentThread]);
    });
    NSLog(@"---h end");

编译结果如下:


超过5秒超时时间后走---h4 再走group里的---h2.png
dispatch_barrier_async(栅栏方法(将两组异步分割开来))
NSLog(@"---00000--%@",[NSThread currentThread]);
    dispatch_queue_t queue=dispatch_queue_create("hehe", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        for (int i=0; i<3; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i=3; i<6; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    dispatch_barrier_async(queue, ^{
        for (int i=6; i<9; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i=9; i<12; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (int i=12; i<15; i++) {
            NSLog(@"---%d--%@",i,[NSThread currentThread]);
        }
    });
    NSLog(@"---ff--%@",[NSThread currentThread]);

编译结果如下:

GCD简单使用_第7张图片
dispatch_barrier_async.png

可以看出前面两个异步先执行完,再执行的后面两个异步。

延时
NSLog(@"---hello");
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0*NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //2s后异步执行
        NSLog(@"---h---come !");
    });
    NSLog(@"---h end");

编译结果如下:

延时2秒.png
  • dispatch_once单例 就不写了。

你可能感兴趣的:(GCD简单使用)