GCD 整理(二)
来源:互联网 发布:无主之地ol激活码淘宝 编辑:程序博客网 时间:2024/06/06 12:40
Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法。
GCD的用法:
dispatch_async
// 后台执行: dispatch_async(dispatch_get_global_queue(0, 0), ^{ // something });
<pre name="code" class="objc" style="line-height: 18px; font-family: Verdana, 'Lucida Grande', Arial, Helvetica, sans-serif;">// 主线程执行: dispatch_async(dispatch_get_main_queue(), ^{ // something });
dispatch_async开启一个异步操作,第一个参数是指定一个gcd队列,第二个参数是分配一个处理事物的程序块到该队列。
dispatch_get_global_queue(0, 0),指用了全局队列。
一般来说系统本身会有3个队列。
global_queue,current_queue,以及main_queue.
获取一个全局队列是接受两个参数,第一个是我分配的事物处理程序块队列优先级。分高低和默认,0为默认2为高,-2为低。
#define DISPATCH_QUEUE_PRIORITY_HIGH 2 #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 #define DISPATCH_QUEUE_PRIORITY_LOW (-2)
dispatch_once
// 一次性执行: static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // code to be executed once });
全局只执行一次,一般用作单例的实现。下面是单例的例子
<pre name="code" class="objc">// 单例+(NewHttp *)share{ static NewHttp *_sharDL = nil; static dispatch_once_t onceDLMgr = 0; dispatch_once(&onceDLMgr, ^{ _sharDL = [[NewHttp alloc] init]; }); return _sharDL;}
dispatch_after
// 延迟2秒执行: double delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ // code to be executed on the main queue after delay });
dispatch_after只是延时提交block,并不是延时后立即执行。所以想用dispatch_after精确控制运行状态的朋友可要注意了~
用dispatch_after的时候就会用到dispatch_time_t变量,但是如何创建合适的时间呢?答案就是用dispatch_time函数,其原型如下:
dispatch_time_t dispatch_time ( dispatch_time_t when, int64_t delta );
第一个参数一般是DISPATCH_TIME_NOW,表示从现在开始。
那么第二个参数就是真正的延时的具体时间。
这里要特别注意的是,delta参数是“纳秒!”,就是说,延时1秒的话,delta应该是“1000000000”=。=,太长了,所以理所当然系统提供了常量,如下:
#define NSEC_PER_SEC 1000000000ull //每秒有多少纳秒。#define USEC_PER_SEC 1000000ull //每秒有多少毫秒#define NSEC_PER_USEC 1000ull //每毫秒有多少纳秒。
dispatch_queue_create
// 自定义dispatch_queue_t dispatch_queue_t urls_queue = dispatch_queue_create("<span style="color: rgb(37, 37, 37); line-height: 28px;"><span style="font-size:12px;">com.example.MyQueue</span></span>", NULL); dispatch_async(urls_queue, ^{ // your code }); dispatch_release(urls_queue);
dispatch_queue_create,创建队列用的,它的参数只有两个,原型如下:
dispatch_queue_t dispatch_queue_create ( const char *label, dispatch_queue_attr_t attr );在网上的大部分教程里(甚至Apple自己的文档里),第二个参数传的是“NULL”。 但是dispatch_queue_attr_t类型是有已经定义好的常量的,所以我认为,为了更加的清晰、严谨,最好如下创建队列:
//串行队列dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", DISPATCH_QUEUE_SERIAL);//并行队列dispatch_queue_t queue = dispatch_queue_create("com.example.MyQueue", DISPATCH_QUEUE_CONCURRENT);
常量就是为了使代码更加“易懂”,更加清晰,既然有,为啥不用呢~
dispatch_suspend
dispatch_suspend != 立即停止队列的运行
dispatch_suspend,dispatch_resume提供了“挂起、恢复”队列的功能,简单来说,就是可以暂停、恢复队列上的任务。但是这里的“挂起”,并不能保证可以立即停止队列上正在运行的block,看如下例子:
dispatch_queue_t queue = dispatch_queue_create("me.tutuge.test.gcd", DISPATCH_QUEUE_SERIAL);//提交第一个block,延时5秒打印。dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:5]; NSLog(@"After 5 seconds...");});//提交第二个block,也是延时5秒打印dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:5]; NSLog(@"After 5 seconds again...");});//延时一秒NSLog(@"sleep 1 second...");[NSThread sleepForTimeInterval:1];//挂起队列 NSLog(@"suspend...");dispatch_suspend(queue);//延时10秒 NSLog(@"sleep 10 second...");[NSThread sleepForTimeInterval:10];//恢复队列 NSLog(@"resume...");dispatch_resume(queue);
运行结果如下:
2015-04-01 00:32:09.903 GCDTest[47201:1883834] sleep 1 second...2015-04-01 00:32:10.910 GCDTest[47201:1883834] suspend...2015-04-01 00:32:10.910 GCDTest[47201:1883834] sleep 10 second...2015-04-01 00:32:14.908 GCDTest[47201:1883856] After 5 seconds...2015-04-01 00:32:20.911 GCDTest[47201:1883834] resume...2015-04-01 00:32:25.912 GCDTest[47201:1883856] After 5 seconds again...
可知,在dispatch_suspend挂起队列后,第一个block还是在运行,并且正常输出。
结合文档,我们可以得知,dispatch_suspend并不会立即暂停正在运行的block,而是在当前block执行完成后,暂停后续的block执行。
所以下次想暂停正在队列上运行的block时,还是不要用dispatch_suspend了吧~
// 合并汇总结果 dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ // 并行执行的线程一 }); dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{ // 并行执行的线程二 }); dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{ // 汇总结果 });
- GCD 整理(二)
- GCD 多线程 (二)
- GCD 多线程 (二)
- 多线程(二) GCD
- 多线程GCD(二)
- iOS GCD(二)
- iOS GCD整理(一)
- GCD整理
- GCD 简单使用(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- GCD深入理解(二)
- GCD 深入理解(二)
- GCD 深入理解(二)
- 20160315 Sail Studio 2244 剪格子,2324 N^3,2230 K好数
- xcode7、iOS 后设置启动图片(Launch Image)
- orcale 数据库里如何修改列名
- 笔记:ios开发基础
- 如何对读写的网格部件字段进行只读控制
- GCD 整理(二)
- MyEclipse中会在taglib那一行有一个错误标志,但是运行的 时候没有问题
- 新建工程配置路径的问题
- No message found under code 'login.userName' for locale 'en_GB' error in spring MVC
- Java 8的新特性—终极版
- 1.[Gradle中文教程系列]跟我学Gradle-Gradle的概述、简介和优势
- 问题 A: 省赛专用题(1)
- JavaScript 进阶教程目录
- IplImage 4通道转3通道