iOS中 GCD-Grand Central Dispath 多线程 ☀️

版权声明:本文为博主原创文章,未经博主允许不得转载。

GCD:Grand Central Dispath "牛逼的中枢调度器";是纯C语言编写的,提供了很多比较强大的函数.

GCD:优势

1.目前是苹果主推的线程管理方式
2.它会自动的利用更多的CPU资源(双核,四核)
3.它会自动的管理线程的生命周期(线程的创建/调度/销毁);
4.程序员只需要告诉GCD自己想要执行的哪些任务,不需要写一行线程管理的代码

#import "ViewController.h"

#define kURLString1 @"http://www.nbsheji.cn/uploadfiles/2010113143922418.jpg"

#define kURLString2 @"http://amuse.nen.com.cn/imagelist/11/21/9as70n3ir61b.jpg"

@interface ViewController ()

@property (retain, nonatomic) IBOutlet UIImageView *FirstView;//第一个图片

@property (retain, nonatomic) IBOutlet UIImageView *secondView;//第二个图片

@property(nonatomic,retain)NSMutableArray *dataSource;//存储请求下来的数据

@end

@implementation ViewController

//懒加载

- (NSMutableArray *)dataSource
{
  if (_dataSource == nil) 
  {
    self.dataSource = [NSMutableArray arrayWithCapacity:0];
  }
return [[_dataSource retain]autorelease];
}```

1.串行队列:(线程同步)添加到这个队列的任务一个接一个的执行(一个任务完成,才再去完成另一个任务)

  • (IBAction)handleSerialQueue:(UIButton *)sender
    {
    //获取系统串行队列

// (1)向系统的创建的串行队列中添加异步任务,还是在主线程中完成;

// (2)向系统创建的串行队列中添加同步任务,会造成线程死锁,导致其他人无法执行;

dispatch_queue_t queue1 = dispatch_get_main_queue();

//01:队列的唯一标识,采用反域名形式

//02:队列的属性类型,也就是标识这个队列是串行队列还是并行队列

// (1)自己创建的串行队列中添加异步任务是在子线程中完成任务;

// (2)自己创建的串行队列中添加同步任务是在主线程中完成任务;

dispatch_queue_t queue2 = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_SERIAL);

/*

//异步任务

//第一个参数:任务添加到队列名称

//第二个参数:block执行任务内容

dispatch_async(queue2, ^{

NSLog(@"任务1 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

});

dispatch_async(queue2, ^{

NSLog(@"任务2 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

});

dispatch_async(queue2, ^{

NSLog(@"任务3 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

});

//释放掉自己的创建的队列,出现create就要释放

dispatch_release(queue2);

*/

//同步任务

dispatch_sync(queue2, ^{

NSLog(@"任务1 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

});

dispatch_sync(queue2, ^{

NSLog(@"任务2 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

});

dispatch_sync(queue2, ^{

NSLog(@"任务3 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

});

// 总结:同步任务:不管在哪一个队列中都是主线程中执行,但是不能将其添加到系统自带的串行队列中;

// 异步任务:在自己创建的串行队列中,在子线程中执行,如果是系统创建的队列在主线程中执行;

}```

2.并行队列 (线程并发) 添加到此队列的任务同时执行  假象.
- (IBAction)handleConcurrentQueue:(UIButton *)sender 
{
//1.获取系统自带的并行队列

//01.队列的优先级

//02.预留参数  给0

dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//2.自己创建并行队列 (一般不自己创建并行队列,系统的并行队列已经够用了)

dispatch_queue_t queue2 = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_CONCURRENT);

//同步任务

dispatch_sync(queue1, ^{

NSLog(@"同步任务%@  %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

});

//异步任务

dispatch_async(queue2, ^{

NSLog(@"任务1%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

});

dispatch_async(queue2, ^{

NSLog(@"任务2%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

});

dispatch_async(queue2, ^{

NSLog(@"任务3%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

//线程间的通信

//由子线程回到主线程

//获取系统的串行队列

dispatch_async(dispatch_get_main_queue(), ^{

NSLog(@"我回到主线程了");

});

});

//释放出现create就要释放

dispatch_release(queue2);

}```

3.分组队列:把多个任务添加到一个分组中执行,此时会在所有的任务完成后会自动发一个通
知,dispatch_group_notifity接收这个消息,然后在所有任务完成之后处理.

  • (IBAction)handleGroupQueue:(UIButton *)sender {

//1.创建并行队列,并执行任务

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

__block typeof(self)weakSelf = self;

//创建分组异步同步任务

dispatch_group_t group = dispatch_group_create();

//01.分组名

//02.要添加的队列名

//03.要执行的任务

dispatch_group_async(group, queue, ^{

NSURL *urlString = [NSURL URLWithString:kURLString1];

NSData *data1 = [NSData dataWithContentsOfURL:urlString];

//使用数组存放请求下来的数据

[weakSelf.dataSource addObject:data1];

});

dispatch_group_async(group, queue, ^{

NSURL *url = [NSURL URLWithString:kURLString2];

NSData *data2 = [NSData dataWithContentsOfURL:url];

[weakSelf.dataSource addObject:data2];

});

//分组中的任务都完成后会自动触发下面的方法

dispatch_group_notify(group, queue, ^{

weakSelf.FirstView.image = [UIImage imageWithData:weakSelf.dataSource[0]];

weakSelf.secondView.image = [UIImage imageWithData:weakSelf.dataSource[1]];

});

//释放分组

dispatch_release(group);

}```

4.障碍队列
- (IBAction)handleBarrierQueue:(UIButton *)sender {

//1.使用障碍队列只能使用自己创建的并列队列,不能使用系统的并行队列

dispatch_queue_t  queue = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_CONCURRENT);

//2.往并行队列中添加任务

dispatch_async(queue, ^{

NSLog(@"A写入文件");

});

dispatch_async(queue, ^{

NSLog(@"B写入文件");

});

dispatch_async(queue, ^{

NSLog(@"C写入文件");

});

//添加障碍,间隔写入和读取的任务,障碍任务之前的任务都完成了才能继续完成障碍任务后面的任务

dispatch_barrier_async(queue, ^{

NSLog(@"我是障碍任务,读取的任务先等会");

});

dispatch_async(queue, ^{

NSLog(@"D读取文件");

});

dispatch_async(queue, ^{

NSLog(@"D读取文件");

});

dispatch_async(queue, ^{

NSLog(@"E读取文件");

});

//3.释放

dispatch_release(queue);

}

只执行一次
- (IBAction)handleOnce:(UIButton *)sender {

static  dispatch_once_t oneToken ;

//

dispatch_once(&oneToken, ^{

NSLog(@"有能耐让我走两次");

});

}

这里需要写一个单例

Helper.h

@interface Helper : NSObject

+ (Helper *)shareHelper;

@end

Helper.h

@implementation Helper

static  Helper *helper = nil;

+ (Helper *)shareHelper{

//VIP

static dispatch_once_t oneToken;

dispatch_once(&oneToken, ^{

helper = [[Helper alloc]init];

});

return helper;

}

@end

重复任务
- (IBAction)handleRepeat:(UIButton *)sender {

//1.获取系统的并行队列

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//2.向队列中添加重复任务

//01.任务重复的次数

//02.任务添加到的队列名称

//03.当前是第几次重复这个任务

dispatch_apply(10, queue, ^(size_t times) {

NSLog(@"我要吃爆米花,这是我第%ld吃",times);

});

}

延迟任务 一个任务要执行的时候先等上一段时间再做
- (IBAction)handlePing:(UIButton *)sender {      //创建一个延迟任务      

//01. DISPATCH_TIME_NOW 表示从当前时间开始     

 //02. 表示过多少秒才去执行任务    

  //03. 串行的主队列 

     dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(55 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{          NSLog(@"延迟任务在主线程中执行");      });  

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

推荐阅读更多精彩内容

  • 1. GCD简介 什么是GCD呢?我们先来看看百度百科的解释简单了解下概念 引自百度百科:Grand Centra...
    千寻_544f阅读 357评论 0 0
  • 多线程 什么是多线程?多线程就是一个进程中可以开启多条线程,每条线程可以并行执行不同的任务,提高执行效率;一个基本...
    西风颂阅读 864评论 1 16
  • 学习多线程,转载两篇大神的帖子,留着以后回顾!第一篇:关于iOS多线程,你看我就够了 第二篇:GCD使用经验与技巧...
    John_LS阅读 603评论 0 3
  • 目录 一、基本概念1.多线程2.串行和并行, 并发3.队列与任务4.同步与异步5.线程状态6.多线程方案 二、GC...
    BohrIsLay阅读 1,557评论 5 12
  • 前言 嘿嘿嘿,精品。 概述 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器”。纯C语...
    Ostkaka丶阅读 1,089评论 0 12