iOS多线程编程之GCD

原创 2015年07月06日 20:21:30

1.GCD介绍

Grand Central Dispatch 简称(GCD)是Apple公司开发的技术,相比NSThread或NSOperation使用方便,并且优点是当处理器为多核时能利用多核的特征来创建线程。它首次发布在Mac OS X 10.6 ,iOS 4及以上也可用。

2.GCD分类

GCD中的FIFO队列称为dispatch queue,它可以保证先进来的任务先得到执行,dispatch queue分为下面3种:一种是串行队列(Serial Dispatch Queue),一种是并行队列(Concurrent Dispatch Queue),还有一个是主队列(Main dispatch queue).

2.1 串行队列(Serial Dispatch Queue)

又称为private dispatch queues,同时只执行一个任务。Serial queue通常用于同步访问特定的资源或数据。当你创建多个Serial queue时,虽然它们各自是同步执行的,但Serial queue与Serial queue之间是并发执行的。

- (void)serialQueue {
	dispatch_queue_t serialQueue = dispatch_queue_create("http://blog.csdn.net/zhangwenhai001", DISPATCH_QUEUE_SERIAL);
	dispatch_async(serialQueue, ^{
		NSLog(@"serialQueue1 -- %@",[NSThread currentThread]);
	});
	dispatch_async(serialQueue, ^{
		NSLog(@"serialQueue2 -- %@",[NSThread currentThread]);
	});
}
运行结果为:

2015-07-06 21:01:44.583 GCD复习[1113:175900] serialQueue1 -- <NSThread: 0x7fccb8e159f0>{number = 2, name = (null)}
2015-07-06 21:01:44.584 GCD复习[1113:175900] serialQueue2 -- <NSThread: 0x7fccb8e159f0>{number = 2, name = (null)}
结论:在serial queue中按顺序执行任务,主线程以外会开一个线程,看运行结果时间.

2.2 并行队列(Concurrent Dispatch Queue)

又称为global dispatch queue,可以并发地执行多个任务,但是执行完成的顺序是随机的。

- (void)concurrentQueue {
	dispatch_queue_t concurrentQueue = dispatch_queue_create("http://blog.csdn.net/zhangwenhai001", DISPATCH_QUEUE_CONCURRENT);
	dispatch_async(concurrentQueue, ^{
		NSLog(@"concurrentQueue1 -- %@",[NSThread currentThread]);
	});
	dispatch_async(concurrentQueue, ^{
		NSLog(@"concurrentQueue2 -- %@",[NSThread currentThread]);
	});
}
运行结果为:

2015-07-06 21:06:02.264 GCD复习[1218:178568] concurrentQueue1 -- <NSThread: 0x7f9c6b715520>{number = 2, name = (null)}
2015-07-06 21:06:02.264 GCD复习[1218:178567] concurrentQueue2 -- <NSThread: 0x7f9c6b5103a0>{number = 3, name = (null)}
2015-07-06 21:06:02.264 GCD复习[1218:178569] concurrentQueue3 -- <NSThread: 0x7f9c6b649c40>{number = 4, name = (null)}
结论:在concurrent queue中,任务是并发执行,并每个任务开一个子线程,看运行结果时间.

2.3 主队列(Main dispatch queue)

它是全局可用的serial queue,它是在应用程序主线程上执行任务的,在程序的RunLoop中执行。

- (void)mainQueue {
	dispatch_queue_t mainQueue = dispatch_get_main_queue();
	dispatch_async(mainQueue, ^{
		NSLog(@"mainQueue1 -- %@",[NSThread currentThread]);
	});
	dispatch_async(mainQueue, ^{
		NSLog(@"mainQueue2 -- %@",[NSThread currentThread]);
	});
	dispatch_async(mainQueue, ^{
		NSLog(@"mainQueue3 -- %@",[NSThread currentThread]);
	});
}
运行结果为:

2015-07-06 21:10:03.982 GCD复习[1239:180152] mainQueue1 -- <NSThread: 0x7ffad0628050>{number = 1, name = main}
2015-07-06 21:10:03.983 GCD复习[1239:180152] mainQueue2 -- <NSThread: 0x7ffad0628050>{number = 1, name = main}
2015-07-06 21:10:03.983 GCD复习[1239:180152] mainQueue3 -- <NSThread: 0x7ffad0628050>{number = 1, name = main}
结论:所有任务会在主线程中阻塞性执行,按顺序一个一个执行,并不会创建新的线程.

3. 系统的Dispatch Queue

3.1 Main Dispatch Queue

主线程队列(Serial Queue), 在程序的RunLoop中执行。

获取方法:

dispatch_queue_t mainQueue = dispatch_get_main_queue();

3.2 Global Dispatch Queue

Global Dispatch Queue: 系统中所有应用程序共用的全局队列(Concurrent Queue), 一般不必创建新的Dispatch Queue,使用此Queue就可以了。

Global Diapacth Queue有4个优先级:High Priority(高)、Default Priority(默认)、Low Priority(低)、Background Priority(后台)。

dispatch_queue_t globalDispatchQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

3.3 举例解释

举例下载图片并刷新UI,main dispatch Queue和global dispatch Queue的结合使用:

- (void)globalQueue {
	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
		//downLoadImage
		dispatch_async(dispatch_get_main_queue(), ^{
			//refresh UI
		});
	});
}

4.dispatch_group_async的使用

dispatch_group_async可以实现监听一组任务是否完成,完成后得到通知执行其他的操作。这个方法很有用,比如你执行三个下载任务,当三个任务都下载完成后你才通知界面说完成的了。

实例代码如下:

- (void)dispatchGroupAsync {
	dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
	dispatch_group_t dispatchGroup = dispatch_group_create();
	
	dispatch_group_async(dispatchGroup, globalQueue, ^{
		NSLog(@"task1--%@",[NSThread currentThread]);
	});
	dispatch_group_async(dispatchGroup, globalQueue, ^{
		[NSThread sleepForTimeInterval:2.0];
		NSLog(@"task2--%@",[NSThread currentThread]);
	});
	dispatch_group_async(dispatchGroup, globalQueue, ^{
		[NSThread sleepForTimeInterval:1.0];
		NSLog(@"task3--%@",[NSThread currentThread]);
	});
	
	dispatch_group_notify(dispatchGroup, globalQueue, ^{
		NSLog(@"dispatch_group_notify queue finished!");
	});
}
运行结果为:

2015-07-06 21:34:08.362 GCD复习[1347:189003] task1--<NSThread: 0x7fdbcb429e70>{number = 2, name = (null)}
2015-07-06 21:34:09.367 GCD复习[1347:189009] task3--<NSThread: 0x7fdbcb61c910>{number = 3, name = (null)}
2015-07-06 21:34:10.367 GCD复习[1347:189005] task2--<NSThread: 0x7fdbcb615660>{number = 4, name = (null)}
2015-07-06 21:34:10.367 GCD复习[1347:189005] dispatch_group_notify queue finished!
结论:

在并行的多个子线程任务结束后能得到通知.

5.dispatch_barrier_async的使用

dispatch_barrier_async是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行,相当于我说执行在哪里就是那里.

但是在concurrentQueue中.

<span style="font-size:14px;">- (void)dispatchBarrierAsync {
	dispatch_queue_t concurrentQueue = dispatch_queue_create("http://blog.csdn.net/zhangwenhai001", DISPATCH_QUEUE_CONCURRENT);
	dispatch_async(concurrentQueue, ^{
		NSLog(@"dispatch_async1 -- %@",[NSThread currentThread]);
	});
	dispatch_barrier_async(concurrentQueue, ^{
		NSLog(@"dispatch_barrier_async -- %@",[NSThread currentThread]);
	});
	dispatch_async(concurrentQueue, ^{
		NSLog(@"dispatch_async2 -- %@",[NSThread currentThread]);
	});
}</span>

运行结果:

2015-07-06 21:44:41.202 GCD复习[1414:192934] dispatch_async1 -- <NSThread: 0x7fb511503fe0>{number = 2, name = (null)}
2015-07-06 21:44:41.203 GCD复习[1414:192934] dispatch_barrier_async -- <NSThread: 0x7fb511503fe0>{number = 2, name = (null)}
2015-07-06 21:44:41.203 GCD复习[1414:192934] dispatch_async2 -- <NSThread: 0x7fb511503fe0>{number = 2, name = (null)}
6.dispatch_apply 

执行block中代码N次.

- (void)dispatchApply {
	dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
	dispatch_apply(3, globalQueue, ^(size_t index) {
		NSLog(@"I`m dispatchApply%zu -- %@",index,[NSThread currentThread]);
	});
}

运行结果为:

2015-07-06 21:51:33.455 GCD复习[1508:196299] I`m dispatchApply0 -- <NSThread: 0x7f9848516f10>{number = 1, name = main}
2015-07-06 21:51:33.455 GCD复习[1508:196322] I`m dispatchApply2 -- <NSThread: 0x7f9848674f50>{number = 3, name = (null)}
2015-07-06 21:51:33.455 GCD复习[1508:196323] I`m dispatchApply1 -- <NSThread: 0x7f9848408940>{number = 2, name = (null)}
结论:

从运行结果得知,dispatch_apply的dispatch_queue_t不能为dispatch_main_queue,因为"I`m dispatchApply0"占用的是主线程.

7.dispatch_once 

block内部的代码在app声明周期内只执行一次.

- (void)dispatchOnce {
	static dispatch_once_t onceToken;
	dispatch_once(&onceToken, ^{
		NSLog(@"I`m dispatch_once_t-- %@",[NSThread currentThread]);
	});
}
运行结果为:

2015-07-06 21:57:33.937 GCD复习[1529:198306] I`m dispatch_once_t-- <NSThread: 0x7f8658518540>{number = 1, name = main}

8.queue的暂停和恢复

使用dispatch_suspend(queue)可以暂停队列中任务的执行,使用dispatch_result(queue)可以继续执行被暂停的队列。


参考:http://blog.csdn.net/totogo2010/article/details/8016129

---end

版权声明:本文为博主原创文章,转载请注明来源:http://blog.csdn.net/zhangwenhai001

iOS 多线程编程之GCD

GCD全称Grand Central Dispatch,是苹果为多核的并行运算提出的解决方案,所以会自动合理地利用更多的CPU内核(比如双核、四核),最重要的是它会自动管理线程的生命周期(创建线程、调...
  • lyqfly07
  • lyqfly07
  • 2015年11月24日 16:45
  • 199

iOS多线程编程之GCD介绍

from:http://www.dreamingwish.com/dream-category/toturial/gcd-guide GCD介绍(一): 基本概念和Dispatch Queue 什...
  • chenyxh2005
  • chenyxh2005
  • 2014年12月25日 21:02
  • 279

iOS多线程编程--GCD

让我们来深入学一下iOS多线程开发中,最有魅力的一种方式GCD。通过这篇文章,可以加深我们对于队列的理解,了解串行、并行、同步、异步等概念...
  • u010262501
  • u010262501
  • 2016年06月05日 23:41
  • 161

[TwistedFate]iOS多线程编程GCD

简介iOS有三种多线程编程的技术,分别是: (一)NSThread (二)Cocoa NSOperation (三)GCD(全称:Grand Central Dispatch) 这三种编程方式...
  • ShadowOfMaster
  • ShadowOfMaster
  • 2016年01月15日 18:59
  • 296

iOS多线程编程GCD

1.GCD简介GCD(Grand Central Dispatch)是系统基于C封装的多线程编程技术。它会自动管理线程的生命周期(创建线程、调度任务、销毁线程)。结合block使用,方便灵活。因为GC...
  • xiaoleileIziyi
  • xiaoleileIziyi
  • 2017年01月02日 19:45
  • 210

iOS多线程编程——浅谈GCD

GCD对于iOS开发者来说肯定不陌生,他和NSThread,NSOperation一起作为iOS开发中主要的三种多线程实现方法,而GCD是最最底层的,所以对于作为一个iOSer,GCD是必须掌握的。...
  • zkh90644
  • zkh90644
  • 2016年07月17日 20:08
  • 2364

iOS多线程编程-GCD

iOS多线程编程-GCD 一、什么是GCD Grand Central Dispatch (GCD)是支持 iOS 和 OS X 多核硬件系统,并发执行任务的技术之一,是苹果公司为多核的并行运算提...
  • Xiao_Long_Li
  • Xiao_Long_Li
  • 2015年11月29日 13:16
  • 211

iOS与OS多线程和内存管理----GCD底层实现

GCD实现 GCD实在内核XNU上实现的,实现Dispatch Queue的软件组建: libdispatch组件,主要提供Dispatch Queue技术; Libc(pthreads)组件,...
  • u011774517
  • u011774517
  • 2017年03月02日 15:09
  • 785

ios多线程学习之GCD线程锁

因为在以前的开发中实在是很少会用到多线程的知识,但是现在手中的项目是做视频开发。 而在视频开发类项目中,最困难的就是逻辑和多线程处理,这几天没事研究了一下线程锁,我觉的一个简答的代码实例,就能体现出 ...
  • my_programe_life
  • my_programe_life
  • 2015年11月30日 00:03
  • 1379

iOS基于GCD开发的定时器

系统提供的NSTimer类,很多的时候内存的释放是一个大问题,尤其是repeat方式的,通过调试发现它是基本上不释放的。我个人就考虑用GCD来实现一套定时器的功能。...
  • wuyoujian0313
  • wuyoujian0313
  • 2016年07月03日 11:38
  • 559
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS多线程编程之GCD
举报原因:
原因补充:

(最多只允许输入30个字)