GCD常用知识

GCD的工作原理是:让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。

一个任务可以是一个函数(function)或者是一个block。 GCD的底层依然是用线程实现,不过这样可以让程序员不用关注实现的细节。

GCD中的FIFO队列称为dispatch queue,它可以保证先进来的任务先得到执行。

dispatch queue分为下面三种:

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

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

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

用GCD实现这个流程的操作比前面介绍的NSThread NSOperation的方法都要简单。代码框架结构如下:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 耗时的操作
    dispatch_async(dispatch_get_main_queue(), ^{
        // 更新界面
    });
});

下载图片的例子

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSURL * url = [NSURL URLWithString:@"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"];
    NSData * data = [[NSData alloc]initWithContentsOfURL:url];
    UIImage *image = [[UIImage alloc]initWithData:data];
    if (data != nil) {
        dispatch_async(dispatch_get_main_queue(), ^{
            self.imageView.image = image;
         });
    }
});

系统给每一个应用程序提供了三个concurrent dispatch queues。这三个并发调度队列是全局的,它们只有优先级的不同。因为是全局的,我们不需要去创建。我们只需要通过使用函数dispath_get_global_queue去得到队列,如下:

dispatch_queue_t globalQ = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

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

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
    [NSThread sleepForTimeInterval:1];
    NSLog(@"group1");
});
dispatch_group_async(group, queue, ^{
    [NSThread sleepForTimeInterval:2];
    NSLog(@"group2");
});
dispatch_group_async(group, queue, ^{
    [NSThread sleepForTimeInterval:3];
    NSLog(@"group3");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
    NSLog(@"updateUi");
});
dispatch_release(group);

dispatch_group_async是异步的方法,运行后可以看到打印结果:
2012-09-25 16:04:16.737 gcdTest[43328:11303] group1
2012-09-25 16:04:17.738 gcdTest[43328:12a1b] group2
2012-09-25 16:04:18.738 gcdTest[43328:13003] group3
2012-09-25 16:04:18.739 gcdTest[43328:f803] updateUi

3、dispatch_barrier_async的使用
dispatch_barrier_async是在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行

dispatch_queue_t queue = dispatch_queue_create("gcdtest.rongfzh.yc", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
    [NSThread sleepForTimeInterval:2];
    NSLog(@"dispatch_async1");
});
dispatch_async(queue, ^{
    [NSThread sleepForTimeInterval:4];
    NSLog(@"dispatch_async2");
});
dispatch_barrier_async(queue, ^{
    NSLog(@"dispatch_barrier_async");
    [NSThread sleepForTimeInterval:4];   

});
dispatch_async(queue, ^{
    [NSThread sleepForTimeInterval:1];
    NSLog(@"dispatch_async3");
});

打印结果:

2012-09-25 16:20:33.967 gcdTest[45547:11203] dispatch_async1
2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_async2
2012-09-25 16:20:35.967 gcdTest[45547:11303] dispatch_barrier_async
2012-09-25 16:20:40.970 gcdTest[45547:11303] dispatch_async3

4、dispatch_apply 
执行某个代码片段N次。

dispatch_apply(5, globalQ, ^(size_t index) {
    // 执行5次
});

转自: http://blog.jobbole.com/69019/

//  后台执行:
 dispatch_async(dispatch_get_global_queue(0, 0), ^{
      // something
 });

 // 主线程执行:
 dispatch_async(dispatch_get_main_queue(), ^{
      // something
 });

 // 一次性执行:
 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
     // code to be executed once
 });

 // 延迟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_queue_t
 dispatch_queue_t urls_queue = dispatch_queue_create("blog.devtang.com", NULL);
 dispatch_async(urls_queue, ^{
   // your code
 });
 dispatch_release(urls_queue);

 // 合并汇总结果
 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), ^{
      // 汇总结果
 });
时间: 2024-10-07 13:15:53

GCD常用知识的相关文章

Linux运维常用知识(4)

linux命令无效-bash: ls: command not found 一次重启后开机,基本所有的命令都不可用,只有少数的命令可用 [[email protected] ~]# ll -bash: ls: command not found [[email protected] ~]# pwd /root [[email protected] ~]# shutdown -r now -bash: shutdown: command not found [[email protected] ~

HTML5常用知识

今日做项目,涉及到native和H5页面的交互 1.document.readyState document.readyState:判断文档是否加载完成.firefox不支持. 这个属性是只读的,传回值有以下的可能: 0-UNINITIALIZED:XML 对象被产生,但没有任何文件被加载. 1-LOADING:加载程序进行中,但文件尚未开始解析. 2-LOADED:部分的文件已经加载且进行解析,但对象模型尚未生效. 3-INTERACTIVE:仅对已加载的部分文件有效,在此情况下,对象模型是有

从零单排入门机器学习:Octave/matlab的常用知识之矩阵和向量

Octave/matlab的常用知识之矩阵和向量 之前一段时间在coursera看了Andrew ng的机器学习的课程,感觉还不错,算是入门了.这次打算以该课程的作业为主线,对机器学习基本知识做一下总结.小弟才学疏浅,如有错误,敬请指导. Andrew的课程选了Octave/matlab为编程语言.他选择这个估计更多是考虑大众性,这门语言容易入门. 然后我觉得学会使用Octave/matlab还是挺有用的.一来是她天生是个数学工具,开始的研究阶段使用她最方便莫属,注意我这里所说的是研究阶段,商用

从零单排入门机器学习:OctaveMatlab的常用知识之画图

OctaveMatlab的常用知识之画图 之前一段时间在coursera看了Andrew ng的机器学习的课程,感觉还不错,算是入门了.这次打算以该课程的作业为主线,对机器学习基本知识做一下总结.小弟才学疏浅,如有错误,敬请指导. 看几个例子即可. 'ro'的含义,r表示红色,o表示o形. 可以记住某些常用的选项. 一条命令画两条线.其实可以多条. 一般来说,用户在新输入plot 命令之后,原图片上的内容将被删除.如果你想保存当前的图片内容并将新创建的图片层叠到原图片上,你可以通过使用hold

MYSQL数据库常用知识整理

Evernote Export MYSQL数据库常用知识整理 什么是MYSQL MYSQL的特性 MYSQL存储引擎的分类以及数据文件的介绍 MYSQL赋权 MYSQL备份与恢复 MYSQL的基本操作:增删查改 MYSQL的基本故障判断与处理 MYSQL的调优 MYSQL主主.主从复制的实现 MYSQL大数据备份和恢复 数据文件的损坏与修复 什么是MYSQL MySQL 是一个开放源码的小型关联式数据库管理系统,开发者为瑞典MySQL AB公司.目前MySQL被广泛地应用在Internet上的中

iOS Dev (26) 初步了解下UIColor的最常用知识

作者:CSDN 大锐哥 地址:http://blog.csdn.net/prevention - 内置的颜色有啥? // Some convenience methods to create colors. These colors will be as calibrated as possible. // These colors are cached. + (UIColor *)blackColor; // 0.0 white + (UIColor *)darkGrayColor; // 0

Python数据分析与挖掘所需的Pandas常用知识

Python数据分析与挖掘所需的Pandas常用知识 前言Pandas基于两种数据类型:series与dataframe.一个series是一个一维的数据类型,其中每一个元素都有一个标签.series类似于Numpy中元素带标签的数组.其中,标签可以是数字或者字符串.一个dataframe是一个二维的表结构.Pandas的dataframe可以存储许多种不同的数据类型,并且每一个坐标轴都有自己的标签.你可以把它想象成一个series的字典项. Pandas常用知识 一.读取csv文件为dataf

全体快三源码开发Python数据分析与挖掘所需的Pandas常用知识

前言 全体快三源码开发 (http://www.1159880099.com) QQ1159880099 Pandas基于两种数据类型:series与dataframe. 一个series是一个一维的数据类型,其中每一个元素都有一个标签.series类似于Numpy中元素带标签的数组.其中,标签可以是数字或者字符串. 一个dataframe是一个二维的表结构.Pandas的dataframe可以存储许多种不同的数据类型,并且每一个坐标轴都有自己的标签.你可以把它想象成一个series的字典项.

Linux 常用知识及故障处理

Linux 常用知识及故障处理 1.修改当前系统语言 比如当前语言是en_US.UTF-8,因环境需要修改为zh_CN.UTF-8 ,首先切换到root,追加一行内容即可. echo 'export LANG="zh_CN.UTF-8"' >> ~/.bashrc 重新登录系统,查看语言变化 echo $LANG 2.Linux系统中根目录下或者新挂载的磁盘目录下有一个叫lost+found,它的作用是什么? 如果你运行fsck命令(文件系统检查和修复命令),它也许会找到一