iOS GCD 示例代码

前言:

1.多线程是面试中很骚的一个环节。
2.遇到一些奇怪的逻辑,说不定就会用上多线程了。
3.每次遇到多线程的问题,我总是遍访群贤。
4.我从没有使用过多线程

代码地址 https://github.com/gityuency/ObjectiveCTools
【类名:GCDViewController】

场景1

多个异步请求并发执行,在都执行完之后再做下一步操作。


场景1.png
/*
 场景1: 有 M 个网络请求, 等 M 个网络请求都结束之后, 再进行第 M + 1 个请求
 备注: 异步请求的 block 里面不要再添加其他异步请求
 */
- (IBAction)CGD_Group:(id)sender {
    
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        
        //这里面已经是一个 异步线程 正在执行的代码范围
        //这里面可以放入大量的计算来造成任务很重的假象
        //如果在这个区域再放入异步操作, 那就是异步套异步, 那就是另外一个故事了..
        
        sleep(2);
        NSLog(@"1 当前线程%@",[NSThread currentThread]);
    });
    
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        sleep(5);
        NSLog(@"2 当前线程%@",[NSThread currentThread]);
    });
    
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        sleep(3);
        NSLog(@"3 当前线程%@",[NSThread currentThread]);
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"任务全部完成,当前线程 %@",[NSThread currentThread]);
    });
}

场景2

多个网络请求并发执行,在都执行完成之后,再做下一步操作,这里的异步请求来自于三方或者官方。


场景2.png
/*
 场景1: 有 M 个请求,等 M 个请求完成之后, 再进行第 M + 1 个请求
 备注: 如果这个请求不是 dispatch_group_async, 那该怎么做.
 */
- (IBAction)GCD_Enter_Leave:(id)sender {
    
    dispatch_group_t group = dispatch_group_create();
    
    dispatch_group_enter(group);
    NSURL *url = [NSURL URLWithString:@"https://github.com/AFNetworking/AFNetworking.git"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    NSURLSession *session=[NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask=[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"3 当前线程%@",[NSThread currentThread]);
        dispatch_group_leave(group);
    }];
    [dataTask resume];
    
    
    dispatch_group_enter(group);
    NSURL *url2 = [NSURL URLWithString:@"https://github.com/oa414/objc-zen-book-cn"];
    NSURLRequest *request2 = [NSURLRequest requestWithURL:url2];
    NSURLSession *session2 = [NSURLSession sharedSession];
    NSURLSessionDataTask *dataTask2 = [session2 dataTaskWithRequest:request2 completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        NSLog(@"4 当前线程%@",[NSThread currentThread]);
        dispatch_group_leave(group);
    }];
    [dataTask2 resume];
    
    
    dispatch_group_enter(group);
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        sleep(3);
        NSLog(@"1 当前线程%@",[NSThread currentThread]);
        dispatch_group_leave(group);
    });
    
    dispatch_group_enter(group);
    dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{
        sleep(2);
        NSLog(@"2 当前线程%@",[NSThread currentThread]);
        dispatch_group_leave(group);
    });
    
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"任务全部完成,当前线程 %@",[NSThread currentThread]);
    });
}

场景3

多个任务按照顺序执行


场景3.png
/*
 (异步线程 并发执行 然后阻塞 然后并发执行)
 1,有 m 个网络请求。
 2,先并发执行其中 n 个。
 3,待这n个请求完成之后再执行第 n+1 个请求。
 4,然后等 第 n+1 个请求完成后再并发执行剩下的 m-(n+1) 个请求。
 */
- (IBAction)GCD_Barrier:(id)sender {
    
    // 创建队列
    dispatch_queue_t queue = dispatch_queue_create("我的名字", DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(queue, ^{
        sleep(3);
        NSLog(@"1 当前线程%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        sleep(5);
        NSLog(@"2 当前线程%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        sleep(2);
        NSLog(@"3 当前线程%@",[NSThread currentThread]);
    });
    dispatch_barrier_async(queue, ^{
        NSLog(@"处理任务 1 2 3");
    });
    dispatch_async(queue, ^{
        sleep(2);
        NSLog(@"4 当前线程%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        sleep(4);
        NSLog(@"5 当前线程%@",[NSThread currentThread]);
    });
    dispatch_barrier_async(queue, ^{
        NSLog(@"处理任务 4 5");
    });
}

场景4

异步线程控制并发数。


场景4.png
/*
 场景1: 系统现在有 2 个空闲线程可以用, 但是同一时间 有 3 个线程要同时访问, 如何安排线程线程访问?
 场景2: 同一时间要下载很多图片, 每次下载都会开辟一个新线程, 但是开辟太多线程会卡顿, 如何控制最大开辟线程数?
 备注: 如果这个请求不是 dispatch_group_async, 那该怎么做.
 */
- (IBAction)GCD_Semaphore:(id)sender {
    
    //创建信号量,参数:信号量的初值,如果小于0则会返回NULL crate的value表示,最多几个资源可访问
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);
    dispatch_queue_t quene = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //任务4 (注意,种情况属于异步线程里面又开了一个异步线程)
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"➡️任务 4 当前线程%@",[NSThread currentThread]);
        NSURL *url = [NSURL URLWithString:@"https://www.163.com/"];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        NSURLSession *session= [NSURLSession sharedSession];
        NSURLSessionDataTask *dataTask=[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSLog(@"✅任务 4 当前线程%@",[NSThread currentThread]);
            dispatch_semaphore_signal(semaphore);
        }];
        [dataTask resume];
    });
    
    //任务1
    dispatch_async(quene, ^{
        //等待降低信号量 -1
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"➡️任务 1 当前线程%@",[NSThread currentThread]);
        sleep(1);
        NSLog(@"✅任务 1 当前线程%@",[NSThread currentThread]);
        //提高信号量 +1
        dispatch_semaphore_signal(semaphore);
    });
    
    //任务2
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"➡️任务 2 当前线程%@",[NSThread currentThread]);
        sleep(1);
        NSLog(@"✅任务 2 当前线程%@",[NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
    });
    
    //任务5
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"➡️任务 5 当前线程%@",[NSThread currentThread]);
        NSURL *url = [NSURL URLWithString:@"https://github.com/oa414/objc-zen-book-cn"];
        NSURLRequest *request = [NSURLRequest requestWithURL:url];
        NSURLSession *session= [NSURLSession sharedSession];
        NSURLSessionDataTask *dataTask=[session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
            NSLog(@"✅任务 5 当前线程%@",[NSThread currentThread]);
            dispatch_semaphore_signal(semaphore);
        }];
        [dataTask resume];
    });
    
    //任务3
    dispatch_async(quene, ^{
        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        NSLog(@"➡️任务 3 当前线程%@",[NSThread currentThread]);
        sleep(1);
        NSLog(@"✅任务 3 当前线程%@",[NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
    });
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,542评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,596评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,021评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,682评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,792评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,985评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,107评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,845评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,299评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,612评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,747评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,441评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,072评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,828评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,069评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,545评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,658评论 2 350

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,848评论 25 707
  • 第一次用数位板画画,感觉似乎爱上了画画*/ω\*)希望自己能坚持下去,如此浮躁的现实生活,能有个安静的爱好太不容易...
    三千烬阅读 702评论 13 4
  • 1 企业能量模型 企业能量模型的概念,以及其中的产品、价格、营销、渠道四大要素。还记得吗?经营企业,就像是推巨石上...
    狮子爸爸阅读 214评论 0 1
  • 本来取名书评,但是又感觉自己读的不够深入,还是读后感更恰当一点吧。 书店老板AJ从第一章开始就以挫人形象示人。就如...
    路其123阅读 140评论 0 0