GCD的使用(一)

  今天是年前最后一天上班,偷了点懒(忏悔中…)。尽管明天就见到爸妈,尽管明天就能喝到排骨藕汤(¯﹃¯),但是还是高兴不起来。发现还是找不准自己的位置,心情总是波动起伏不定。有时候因为一句话、一件事,搞得自己魂不守舍,就像杜甫和李清照的诗句一样,完全是两个极端,想趁着过年这段时间,放下心中的包袱,赶紧调整自己,还是写博客能让心中平静一些。

漫卷诗书喜欲狂,白日放歌须纵酒。

感月吟风多少事,如今老去无成,谁怜憔悴更凋零,试灯无意思,踏雪没心情。

  今天讲讲GCD的使用。
  首先看队列,队列可以分为并行队列和串行队列,队列可以分为同步执行和异步执行。
  同步执行可以分为串行队列的同步执行和并行队列的同步执行,异步执行又可以分为串行队列的异步执行和并行队列的异步执行。
  下面会说明串行队列与并行队列的同步执行,串行队列与并行队列的异步执行。并且会说明同步执行和异步执行的区别。先提取一下公共方法。

#pragma mark - 返回当前线程
- (NSThread *)getCurrentThread
{
    return [NSThread currentThread];
}

#pragma mark - 模拟线程耗时
- (void)currentThreadSleep:(NSTimeInterval)timer
{
    [NSThread sleepForTimeInterval:timer];
}

#pragma mark - 获取主队列
- (dispatch_queue_t)getMainQueue
{
    return dispatch_get_main_queue();
}

#pragma mark - 获取全局队列
- (dispatch_queue_t)getGlobalQueue
{
    //默认优先级DISPATCH_QUEUE_PRIORITY_DEFAULT
    return dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
}

  先看看串行队列(Serial Queue)与 并行队列(Concurrent Queue)的区别。这两个队列都遵循先入先出原则,不同的是串行队列要等前面的任务出队列执行完成后,下个任务才能出队列执行。并行队列只要前面的任务出队列了,还有空余线程,不管前面的任务是否执行完,下一个任务都可以出队列。

#pragma mark - 创建并行队列 string 并行队列的标记
- (dispatch_queue_t)getConcurrentQueue:(char *)string
{
    return dispatch_queue_create(string, DISPATCH_QUEUE_CONCURRENT);
}

#pragma mark - 创建串行队列 string 串行队列的标记
- (dispatch_queue_t)getSerialQueue:(char *)string
{
    return dispatch_queue_create(string, DISPATCH_QUEUE_SERIAL);
}

一 同步执行

#pragma mark - 同步执行
- (void)sync:(dispatch_queue_t)queue
{
    for (int i = 0 ; i < 3 ; i ++ )
    {
        dispatch_sync(queue, ^{
            [self currentThreadSleep:1];
            NSLog(@"当前执行线程%@",[self getCurrentThread]);
            NSLog(@"执行%d",i);
        });
        NSLog(@"%d执行完毕",i);
    }
    NSLog(@"所有队列使用同步方式执行完毕");
}

- (IBAction)btn1Click:(id)sender {
    NSLog(@"同步执行串行队列");
    [self sync:[self getSerialQueue:"syn.serial.queue"]];
}
- (IBAction)btn2Click:(id)sender {
    NSLog(@"同步执行并行队列");
    [self sync:[self getConcurrentQueue:"syn.concurrent.queue"]];
}
同步执行串行队列 2018-02-09 下午10.18.01.png
同步执行并行队列 2018-02-09 下午10.19.07.png

  从上面的示例可以知道,同步执行方式来执行队列不会开辟新的线程,会在当前线程中执行任务。当前线程是主线程,就会阻塞主线程,造成UI卡死的现象。在同一个线程执行,串行队列和并行队列使用同步执行的结果是一样的,都必须等到上一个任务出队列并且执行完成才能执行下个任务。

二 异步执行

#pragma mark - 异步执行
- (void)async:(dispatch_queue_t)queue
{
    dispatch_queue_t serialQueue = [self getSerialQueue:"serialQueue"];
    
    for (int i = 0 ; i < 3 ; i ++ )
    {
        dispatch_async(queue, ^{
            [self currentThreadSleep:2];
            
            NSThread * currentThread = [self getCurrentThread];
            
            //同步锁
            dispatch_sync(serialQueue, ^{
                NSLog(@"sleep的线程%@",[self getCurrentThread]);
                NSLog(@"当前输出内容的线程%@",currentThread);
                NSLog(@"执行%d:%@",i,queue);
            });
            
        });
        NSLog(@"%d执行完毕",i);
    }
    NSLog(@"使用异步方式添加队列");
}

- (IBAction)btn3Click:(id)sender {
    NSLog(@"异步执行串行队列");
    [self async:[self getSerialQueue:"asyn.serial.queue"]];
    
    //dispatch_saync 开辟了新线程number = 3来执行block中的内容,block外的东西依旧在之前的线程执行
}
- (IBAction)btn4Click:(id)sender {
    NSLog(@"异步执行并行队列");
    [self async:[self getConcurrentQueue:"asyn.concurrent.queue"]];
}
异步执行串行队列 2018-02-09 下午10.20.56.png
异步执行并行队列2018-02-09 下午10.21.10.png

  异步执行同样也分为串行队列的异步执行和并行队列的异步执行。dispatch_async和dispatch_sync的区别是它会开辟新的线程,不会阻塞当前线程。异步队列的特点是只要要可用的线程,任务就会出队列执行,而不关心之前出队列的任务(block)是否执行完毕。

三 延时执行

  GCD中使用dispatch_after()函数来延时执行队列中的任务,dispatch_after()是异步执行队列中的任务的,也就是说使用dispatch_after()不会阻塞当前任务。等到延时时间到了以后就会开辟一个新的线程然后执行队列中的任务。

#pragma mark - 延时操作
- (void)deferPerform:(double)time
{
    dispatch_time_t delayTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t) (time * NSEC_PER_SEC));
    dispatch_after(delayTime, [self getGlobalQueue], ^{
        NSLog(@"执行线程:%@ \n 延迟%f秒执行 ",[self getCurrentThread],time);
    });
}

四 队列的优先级

  队列有优先级,分为4个级别 High > Default > Low > Background。上面在获取全局队列时可以执行队列的优先级,并且可以使用dispatch_set_target_queue()函数将一个队列的优先级赋值给另一个队列。

#pragma mark - 1为全局队列指定优先级
- (void)globalQueuePriority
{
    //高 > 默认 > 低 > 后台
    dispatch_queue_t queueHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_queue_t queueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_queue_t queueLow = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
    dispatch_queue_t queueBackground = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    
    //一般会按照这个优先级执行,但是不是绝对的,一般使用DISPATCH_QUEUE_PRIORITY_DEFAULT
    dispatch_async(queueLow, ^{
        NSLog(@"Low:%@",[self getCurrentThread]);
    });
    
    dispatch_async(queueBackground, ^{
        NSLog(@"Background:%@",[self getCurrentThread]);
    });
    
    dispatch_async(queueDefault, ^{
        NSLog(@"Default:%@",[self getCurrentThread]);
    });
    
    dispatch_async(queueHigh, ^{
        NSLog(@"High:%@",[self getCurrentThread]);
    });
}

#pragma mark - 2自创的队列指定优先级
- (void)setPriority
{
    //将queueHigh的优先级赋值给queue队列
    dispatch_queue_t  queue = [self getSerialQueue:"serialQueue"];
    dispatch_queue_t queueHigh = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
    dispatch_set_target_queue(queue, queueHigh);
}

  还有GCD比较高级的用法没有时间讲,下次有时间再说。明天还要赶早火车。最后送上那些花儿-朴树,晚安~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 200,738评论 5 472
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,377评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 147,774评论 0 333
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,032评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,015评论 5 361
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,239评论 1 278
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,724评论 3 393
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,374评论 0 255
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,508评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,410评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,457评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,132评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,733评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,804评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,022评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,515评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,116评论 2 341

推荐阅读更多精彩内容