iOS开发技术分享iOS开发资料收集区将来跳槽用

牛逼的中枢调度器

2016-07-18  本文已影响68人  来金德瑞

简介

核心概念

GCD中有两个核心概念:

GCD的使用步骤

  1. 指定任务,确定想做的事情
  2. 将任务添加到队列中,GCD会自动将队列中的任务取出来放到对应的线程中执行。队列的取出遵循队列的FIFO原则:先进先出,后进后出

执行任务

GCD中有两个可以用来执行任务的函数

//queue:队列;block:任务
void dispatch_sync(dispatch_queue_t queue,dispatch_block_t block);
//queue:队列;block:任务
void dispatch_async(dispatch_queue_t queue,dispatch_block_t block);

队列的类型

GCD中的队列可以分为两大类型:

总结

使用例子

  1. 同步函数+主队列
-(void)syncMain{
    NSLog(@"begin");
    
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    dispatch_sync(queue,^{
        NSLog(@"1---%@",[NSThread currentThread]);
    });
    dispatch_sync(queue,^{
        NSLog(@"2---%@",[NSThread currentThread]);
    });
    dispatch_sync(queue,^{
        NSLog(@"3---%@",[NSThread currentThread]);
    });
    
    NSLog(@"end");
    
    //注意:使用sync函数往当前队列中添加任务,会卡住当前的串行队列,除了begin其他都不会被打印。
}
  1. 异步函数+主队列
- (void)asyncMain
{
    
    dispatch_queue_t queue = dispatch_get_main_queue();
    
    dispatch_async(queue, ^{
        NSLog(@"1-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3-----%@", [NSThread currentThread]);
    });
    
    //注意:不会开启新线程。只会在主队列中执行,失去了异步函数的功能。
}
  1. 同步函数+串行队列
-(void)syncSerial{

    dispatch_queue_t queue = dispatch_queue_create("com.queue",DISPATCH_QUEUE_SERIAL);
    
    dispatch_sync(queue,^{
        NSLog(@"1---%@",[NSThread currentThread]);
    })
    dispatch_sync(queue,^{
        NSLog(@"2---%@",[NSThread currentThread]);
    })
    dispatch_sync(queue,^{
        NSLog(@"3---%@",[NSThread currentThread]);
    })
    
    //注意:不会开启新的线程,在当前线程执行任务。任务是串行的,执行完一个任务,再执行下一个任务
}
  1. 异步函数+串行队列
- (void)asyncSerial
{
    
    dispatch_queue_t queue = dispatch_queue_create("com.queue", DISPATCH_QUEUE_SERIAL);
    
    dispatch_async(queue, ^{
        NSLog(@"1-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"2-----%@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"3-----%@", [NSThread currentThread]);
    });
    
    注意:会开启新的线程,但是任务是串行的,执行完一个任务,再执行下一个任务
}
  1. 同步函数+并发队列
- (void)syncConcurrent
{
    
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    dispatch_sync(queue, ^{
        NSLog(@"1-----%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"2-----%@", [NSThread currentThread]);
    });
    dispatch_sync(queue, ^{
        NSLog(@"3-----%@", [NSThread currentThread]);
    });
    
    //注意:不会开启新的线程。串行执行任务。
}

  1. 异步函数+并发队列:可以同时开启多条线程,是最常用的方式
- (void)asyncConcurrent
{
    // 1.获得全局的并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 2.将任务加入队列
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i<10; i++) {
            NSLog(@"1-----%@", [NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i<10; i++) {
            NSLog(@"2-----%@", [NSThread currentThread]);
        }
    });
    dispatch_async(queue, ^{
        for (NSInteger i = 0; i<10; i++) {
            NSLog(@"3-----%@", [NSThread currentThread]);
        }
    });
    

各种队列的执行效果

全局并发队列 手动创建串行队列 主队列(串行队列)
同步(sync) 不会开启新线程串行执行任务 没有开启新线程串行执行任务 没有开启新线程串行执行任务会卡死
异步(async) 有开启新线程并发执行任务 有开启新线程串行执行任务 没有开启新线程串行,执行任务

GCD的其他用法

用法一

// 作用:在并行队列中,等待前面的所有并行操作完成,然后执行dispatch_barrier_async中的操作,然后恢复原有执行状态,继续并行执行
void dispatch_barrier_async(dispatch_queue_t queue,dispatch_block_t block);

用法二

//作用:延迟执行
void dispatch_after(dispatch_time_t when,dispatch_queue_t queue,dispatch_block_t block);

用法三

//作用:block中的代码块只被执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken,^{
    //需要执行的代码块
});

用法三

    //作用:文件剪切,快速迭代
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    NSString *from = @"/Users/Anthony/Desktop/From";
    NSString *to = @"/Users/Anthony/Desktop/To";
    
    NSFileManager *mgr = [NSFileManager defaultManager];
    NSArray *subPaths = [mgr subpathsAtPath:from];
    
    dispatch_apply(subPaths.count, queue, ^(size_t index) {
       
        NSString *subPath = subPaths[index];
        NSString *fromFullPath = [from stringByAppendingPathComponent:subPath];
        NSString *toFullPath = [to stringByAppendingPathComponent:subPath];
        
        [mgr moveItemAtPath:fromFullPath toPath:toFullPath error:nil];
        
        NSLog(@"%@--%@",[NSThread currentThread],subPath);
    });
    

用法四

//队列组
dispatch_queue_t queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);�dispatch_group_t group = dispatch_group_create();
//下载图片
dispatch_group_async(dispatch_group_t group,dispath_queue_t queue,^{});
//(保证执行完组里面的所有任务之后,再执行notify函数里面的block)
dispatch_group_notify(dispatch_group_t group,
dispatch_queue_t queue,
dispatch_block_t block);
上一篇 下一篇

猜你喜欢

热点阅读