iOS中多线程GCD使用(一)

最近遇到这一块的多线程开发,索性直接学习一下了,我们来介绍一下GCD的详细使用
GCD :全称是 Grand Central Dispatch 我们也称之为dispatch 闭包(Closure)函数
GCD队列包含两种:串行队列和并行队列
使用GCD创建队列的两种形式

  1. GCD串行队列创建方式
下面这种是创建一个串行GCD队列,
 dispatch_queue_t  创建一个队列 
dispatch_queue_creat  后面会带有两个参数 也就是队列标示符,
尽量设置成唯一的,使用我们的额工程设置,防止和其他队列冲突
DISPATCH_QUEUE_SERIAL  表示我们要创建一个串行GCD队列
串行队列:FIFO(先进先出原则)也就是说队列中的block函数是按照先进先出的顺序去执行,也就是单线程执行
一般我们在做下载任务时会用到串行队列下载,提高执行效率

dispatch_queue_t queue = 
dispatch_queue_creat("com.example.serial",DISPATCH_QUEUE_SERIAL);



  1. GCD并发队列创建方式
并发执行 ,block 被分发到多个线程中去执行
并发执行创建方式
dispatch_queue_t  queue = 
dispatch_queue_create("com.dispatch.concurrent",DISPATCH_QUEUE_CONCURRENT); 
  1. 获取全局的并发队列
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
获取程序进程缺省产生的并发队列,可根据优先级来选择高、中、低三个优先级,
由于这个是全局有系统控制的队列,所以我们无法对其进行 dispatch_resume()  继续  和 dispatch_suspend() 中断  

学习注意点:
一个APP中可能有多个队列,但是每个队列并不一定只有一个线程,这个是我们的注意点,可能每个队列有多个线程,
而并发队列会根据当前手机的CPU利用情况产生合理的线程数,
如果觉得复杂,可以把队列理解成一个简单的线程池管理对象就好,明白线程需要有一个人去管理


  1. 最后一种获取主线程队列
dispatch_queue_t queue = dispatch_get_main_queue();
获取主线程的dispatch队列,实际上是一个串行队列,同样苹果是不允许我们来操作这个队列的,这个队列的执行,是有系统给予的,不允许我们打断或者继续。

怎么创建一个block块呢

那么我们这个block块所在的队列是串行还是并行呢,就要看我们加载那个队列里面了

异步block任务:

  • dispatch_asyn(dispatch_get_main_queue(),^{
    wirte code : here
    // block 内部我们需要实现的功能
    这个是一个异步执行block,我们添加在主队列里面了,也就是说我们这个是串行任务
    });

  • dispatch_asyn(queue,^{
    这个block任务我们也是添加到一个队列中,这个queue, 如果是串行队列,那就是串行任务,反之,就是并发任务线程,同样,这个也是异步的
    });

同步block 任务块

  • dispatch_syn(dispatch_get_main_queue(),^{
    在主队列中进行同步执行block内部的代码,这个是阻塞线程的,如果我们要请求一个图片,用这个来发送请求,这个任务是跑在主线程的,并且是串行执行的,会阻塞当前线程,直到这个任务结束,用户才可以操作,一般我们是不会这么做的,这样做的后果就是如果数据很大,就会产生思死锁
    });

下面我们使用GCD模仿一个网络请求模型

dispatch_asyn(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0),^{
// 子线程中开始网络请求数据
//更新数据Model
回到主线程刷新UI界面
dispatch_asyn(dispatch_get_main_queue(),^{
在主线程中更新UI代码写在这里
});
});

线程安全

  1. 写数据
  2. 共享数据
  3. 读数据

我们怎么才能保证我们在操作数据库的时候保证每次只有一个线程进行写数据,保证数据的完整性呢,我们可以用串行队列来操作,或者使用lock (锁)来进行操作

写数据串行队列保护如下写法

// 创建一个串行队列
dispatch_queue_t queue = dispatch_queue_create("com.dispatch_rw",DISPATCH_QUEUE_SERIAL);
//写数据到数据库
- (BOOL)writeDataToDB:(NSString  *)string{
//异步串行线程,保证了数据的读写完整性,每次写数据,都要等待上一个线程写入完毕后才开始下一个线程
dispatch_async(queue,^{
  // write database;
 coding .....
});

}

GCD中还有一些其他常用的函数,如下:

同步函数
void dispatch_apply(size_t iterations,dispatch_queue_t queue,void (^block)(size_t));
这个函数会重复执行block内的内容,同时这个方法是同步返回,也就是说要等到所有的block执行完毕才返回,
如果需要异步返回,嵌套在dispatch_async中来使用,同时多个任务的运行是否支持并发还是串行依赖于所在的队列

异步写锁函数,
dispatch_barrier_async(dispatch_queue_t queue,dispatch_block_t block);
这个函数可以设置同步执行的block,他会等到他加入队列之前的block执行完毕后,才开始执行。
在它之后的加入的block,则等待这个block执行完毕后才开始执行。

dispatch_barrier_sync(dispatch_queue_t queue, dispatch_block_t block);
这个是同步返回函数,其他使用和上面一样
//延迟函数
dispatch_after(dispatch_time_t when,dispatch_queue_t queue,dispatch_block_t block);
延迟执行block

// 调换队列函数
diapatch_set_target_queue(dispatch_object_t object,dispatch_queue_t queue);
这个函数会把需要执行的任务对象指定到不同的队列中去处理,这个任务对象可以是dispatch队列,也可以是dispatch源,而且这个过程可以是动态的,可以实现队列的调度管理等,
形如两个队列 A 和 B 可以把A 指派到 B
dispatch_set_target_queue(A,B);
那么A队列还未运行的block会在B队列中运行,这个时候我们暂停A队列。
dispatch_suspend(A);
这个时候只会暂停A中原来的block的执行,B的block则不受影响如果暂停B的运行,则会暂停A的运行

dispatch 队列不支持cancle  (取消) 

没有实现dispatch_cancle ( )函数 







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

推荐阅读更多精彩内容