GCD6: 在GCD上异步执行非UI相关任务

讨论:在主队列、串行队列和并发队列上异步执行代码块才能见识到 GCD 的真正实力。

要在分派队列上执行异步任务,你必须使用下面这些函数中的其中一个:

dispatch_async为了异步执行向分派队列提交一个 Block Object(2 项都通过参数指定)

dispatch_async_f为了异步执行向分派队列提交一个 C 函数和一个上下文引用(3 项通过参数参数指定) 

dispatch_async 和dispatch_sync的区别

dispatch_sync(),同步添加操作。他是等待添加进队列里面的操作完成之后再继续执行。

dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);NSLog(@"1");dispatch_sync(concurrentQueue, ^(){NSLog(@"2");[NSThread sleepForTimeInterval:10];NSLog(@"3");});NSLog(@"4");
输出 : 11:36:25.313 GCDSeTest[544:303] 1
11:36:25.313 GCDSeTest[544:303] 2
11:36:30.313 GCDSeTest[544:303] 3//模拟长时间操作
11:36:30.314 GCDSeTest[544:303] 4

dispatch_async ,异步添加进任务队列,它不会做任何等待

dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);NSLog(@"1");dispatch_async(concurrentQueue, ^(){NSLog(@"2");[NSThread sleepForTimeInterval:5];NSLog(@"3");});NSLog(@"4");
输出:11:42:43.820 GCDSeTest[568:303] 111:42:43.820 GCDSeTest[568:303] 411:42:43.820 GCDSeTest[568:1003] 211:42:48.821 GCDSeTest[568:1003] 3//模拟长时间操作时间

实例:

写一个 iOS APP, 它能从网络的 URL 上下载一个图片。下载完 成之后,APP 应该将图片展示给用户。 

 

1、我们在并发队列上异步的启动一个 block object。

2、在这个 block 中我们使用 dispatch_sync 函数来启动另一个 Block Object,以从 URL 上下载图片。我这样做的目的是想让并发队列中剩余的代码能够等到图片下载完成之后在继续执行。从一个异步代码块上同步下载一个 URL 可以保持这个队列运行同步函数,而不是主线程。当我们从主线程角度来看的话整个运作仍是异步的。我们关心的问题是在下载图片的过程中没有阻塞主线程。

3、图片下载完毕后,为了在 UI 上将图片展示给用户,我们会在主线程上同步执行一个 Block 

 

我们计划的框架:
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_async(concurrentQueue, ^{ __block UIImage *image = nil; dispatch_sync(concurrentQueue, ^{ /* Download the image here */ }); dispatch_sync(dispatch_get_main_queue(), ^{ /* Show the image to the user here on the main queue*/ }); });

详细代码为:

- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_async(concurrentQueue, ^{__block UIImage *image = nil;dispatch_sync(concurrentQueue, ^{//开始下载图片NSString *urlString = @"http://a.hiphotos.baidu.com/image/pic/item/eac4b74543a9822677de5a5c8982b9014a90ebaa.jpg";NSURL *url = [NSURL URLWithString:urlString];NSURLRequest *request = [NSURLRequest requestWithURL:url];NSError *downloadError = nil;NSData *imageData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&downloadError];if (downloadError == nil && imageData != nil) {image = [UIImage imageWithData:imageData];//获得了图片
            }else if (downloadError != nil){NSLog(@"Error happended : %@",downloadError);}else{NSLog(@"No data could get downloaded from the URL");}});dispatch_sync(dispatch_get_main_queue(), ^{//主线程上展示图片if (image != nil) {UIImageView *imageView = [[UIImageView alloc]initWithFrame:self.view.bounds];[imageView setImage:image];[imageView setContentMode:UIViewContentModeScaleAspectFit];[self.view addSubview:imageView];}else{NSLog(@"Image isn't downloaded. Nothing to display.");}});});
}

下面我们来看另一个例子:

假设我们在磁盘的一个文件内存储了 1000 个随机数字的数组,我们想把这个数组加载到内存,让数字按照升序排列然后展示给用户。
如果我们没有数组,那为什么我们不先创建一个数组然后再进行加载,最后展示出来呢? 

 下面两个方法帮助我们在设备上找某文件

- (NSString *)fileLocation{//获得文件夹位置NSArray *folders = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);//见详解1if ([folders count] == 0) {return nil;}//找到了NSString *documentsFolder = [folders objectAtIndex:0];//返回文件目录  .../list.txtreturn [documentsFolder stringByAppendingPathComponent:@"list.txt"];
}
- (BOOL) hasFileAlreadyBeenCreated{BOOL result = NO;NSFileManager *fileManager = [[NSFileManager alloc]init];//判断.../list.txt文件是否已经创建if ([fileManager fileExistsAtPath:[self fileLocation]]) {return YES;}return result;
}

如果没有我们自己创建一个数组并存入磁盘,然后再从磁盘读出该数组,对该数组里的数进行排序显示:

- (void)fixNumbers{dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);dispatch_async(concurrentQueue, ^{NSUInteger numberOfValuesRequired = 1000;if ([self hasFileAlreadyBeenCreated] == NO) {//如果没有这1000个随机数的数组,我们创建一个dispatch_sync(concurrentQueue, ^{NSMutableArray *arrayOfRandomNumbers = [[NSMutableArray alloc]initWithCapacity:numberOfValuesRequired];for (NSUInteger counter = 0; counter < numberOfValuesRequired; counter++) {//unsigned int randomNumber = arc4random()%((unsigned int)RAND_MAX + 1);unsigned int randomNumber = arc4random()%1000;[arrayOfRandomNumbers addObject:[NSNumber numberWithUnsignedInt:randomNumber]];}//然后将这个数组存入磁盘/*BOOL isWrite = [arrayOfRandomNumbers writeToFile:[self fileLocation] atomically:YES];NSLog(@"%d",isWrite);这句代码打印出的是0 没有写入磁盘. 应该是因为arrayOfRandomNumbers是可变数组不能够写入. 要将它转成NSArray*/NSArray *writeArray = [NSArray arrayWithArray:arrayOfRandomNumbers];BOOL isWrite = [writeArray writeToFile:[self fileLocation] atomically:YES];NSLog(@"%d",isWrite);});}__block NSMutableArray *randomNumbers = nil;//在磁盘中读取这些数并且排序dispatch_sync(concurrentQueue, ^{if ([self hasFileAlreadyBeenCreated]) {//读取randomNumbers = [[NSMutableArray alloc]initWithContentsOfFile:[self fileLocation]];NSLog(@"%@",[self fileLocation]);//排序[randomNumbers sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {NSNumber *number1 = (NSNumber *)obj1;NSNumber *number2 = (NSNumber *)obj2;return [number1 compare:number2];}];}});dispatch_async(dispatch_get_main_queue(), ^{if ([randomNumbers count] > 0) {for (int i = 0; i < randomNumbers.count; i++) {NSLog(@"%d",[(NSNumber *)[randomNumbers objectAtIndex:i] unsignedIntValue]);}}});});
}

 

详解1: 

iOS中NSSearchPathForDirectoriesInDomains()方法的学习:

FOUNDATION_EXPORT NSArray *NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directory, NSSearchPathDomainMask domainMask, BOOL expandTilde);

 第一个参数NSSearchPathDirectory directory 在iOS中常用NSDocumentDirectory , NSDocumentationDirectory  ,NSDownloadsDirectory这三个参数.下面是测试结果

NSDocumentDirectory

-(NSString *) dataFilePath { NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES);NSString *documentsDirectory=[paths objectAtIndex:0];return [documentsDirectory stringByAppendingPathComponent:@"data.plist"];}

return value:
path:/Users/admin/Library/Application Support/iPhone Simulator/5.0/Applications/4BC5DA66-B3CA-4056-927B-999BC4DBF3CE/Documents/data.plist

NSDocumentationDirectory

-(NSString *) dataFilePath {NSArray *paths =NSSearchPathForDirectoriesInDomains(NSDocumentationDirectory , NSUserDomainMask, YES); NSString *documentsDirectory=[paths objectAtIndex:0];return [documentsDirectory stringByAppendingPathComponent:@"data.plist" ];}

return value:
path:/Users/admin/Library/Application Support/iPhone Simulator/5.0/Applications/4BC5DA66-B3CA-4056-927B-999BC4DBF3CE/Library/Documentation/data.plist

NSDownloadsDirectory

-(NSString *) dataFilePath { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDownloadsDirectory, NSUserDomainMask, YES); NSString *documentsDirectory=[paths objectAtIndex:0]; return [documentsDirectory stringByAppendingPathComponent:@"data.plist" ];}

return value:
path:/Users/admin/Library/Application Support/iPhone Simulator/5.0/Applications/4BC5DA66-B3CA-4056-927B-999BC4DBF3CE/Downloads/data.plist
 

总结:

因为应用是在沙箱(sandbox)中的,在文件读写权限上受到限制,只能在几个目录下读写文件:

  • Documents:应用中用户数据可以放在这里,iTunes备份和恢复的时候会包括此目录
  • tmp:存放临时文件,iTunes不会备份和恢复此目录,此目录下文件可能会在应用退出后删除
  • Library/Caches:存放缓存文件,iTunes不会备份此目录,此目录下文件不会在应用退出删除

 


转载于:https://www.cnblogs.com/safiri/p/4075992.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/359468.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

带有Java 8,lambda表达式和Mockito-Java8附加组件的更紧凑的Mockito

Mockito-Java8是一组Mockito附加组件&#xff0c;它们利用Java 8和lambda表达式使Mockito的模拟更加紧凑。 在2015年初&#xff0c;我进行了简短的演讲&#xff0c; Java 8为测试带来了力量&#xff01; 我在GeeCON TDD 2015和DevConf.cz 2015上发表了演讲。在我使用4个示例的演…

ContentProvider与ContentResolver使用

例如以下内容为从网络转载&#xff1a;使用ContentProvider共享数据&#xff1a;当应用继承ContentProvider类&#xff0c;并重写该类用于提供数据和存储数据的方法&#xff0c;就能够向其它应用共享其数据。虽然使用其它方法也能够对外共享数据&#xff0c;但数据訪问方式会因…

cshtml中引用css_ASP.NET CoreMVC 中的控制器

Controller in ASP.NET Core MVC在本节中&#xff0c;我们将讨论 Controller 是什么以及它在 ASP.NET Core MVC 中的作用。Fiddler需要大家提前装一个工具&#xff0c;https://www.telerik.com/fiddlerFiddler 是一个 http 协议调试代理工具&#xff0c;它能够记录并检查所有你…

小学阅读方法六种_小学生掌握了这些语文答题方法,轻松应对阅读理解,不再是难事...

家长们都知道&#xff0c;孩子们在学习数学的时候&#xff0c;重要的就是数学的一些公式&#xff0c;只要把数学公式记牢&#xff0c;做很多题的时候灵活运用&#xff0c;就可以解答。今天我们来看看&#xff0c;语文方面也有一些答题公式&#xff0c;当孩子们完全掌握了这些公…

hdu--4028--dp

这个dp我没做出来啊...其实不难..主要题意没理解好 fuck. 给你1-N这N个数 一共2^N-1个子集 每个子集的LCM值>M的情况数有多少种 我也是醉了 这么个题目 给我套他那个题面 硬是没看懂 他在问什么 还是 英语太渣了 然后就是个 状态转移方程的考虑了 map<LL,LL>dp[size]…

敏捷中gwt含义_在您的GWT应用程序中添加JSON功能

敏捷中gwt含义JSON简介 在Web应用程序上工作时&#xff0c;总是会出现客户端-服务器数据交换的问题。 在此问题上有多种方法&#xff0c;其中许多使用XML进行交换。 执行此任务的一种不太知名的格式是JSON。 JSON&#xff08;JavaScript对象表示法&#xff09;是一种轻量级的数…

c++ 经典代码_C语言经典100题(31)

1上期答案揭晓首先给大家看看上一篇文章C语言经典100题(30)中第三部分编程题的答案&#xff1a;#include int main( ){ long ge,shi,qian,wan,x; printf("请输入 5 位数字&#xff1a;"); scanf("%ld",&x); wanx/10000; /*分解出万…

$ 与 # 区别

# 会根据不同类型而生产字符串&#xff0c;如 String 类型 : aa ---> aa,长整型Long:123 ---> 123$ 表示原生类型&#xff0c;如 String 类型 : aa ---> aa,长整型Long:123 ---> 123转载于:https://www.cnblogs.com/svennee/p/4078824.html

JAX-RS 2.x与Spring MVC:返回对象列表的XML表示

JSON是所有REST * API的王者&#xff0c;但是您仍然可能需要公开多种表示形式&#xff0c;包括XML。 使用JAX-RS和Spring MVC都非常简单。 实际上&#xff0c;唯一要做的就是用JAXB注释对从API调用返回的POJO进行注释。 但是&#xff0c;我认为序列化对象列表时&#xff0c;JA…

android读取excel文件_python里读写excel等数据文件的几种常用方式

python处理数据文件第一步是要读取数据&#xff0c;文件类型主要包括文本文件(csv、txt等)、excel文件、数据库文件、api等。下面整理下python有哪些方式可以读取数据文件。1. python内置方法(read、readline、readlines)read() &#xff1a; 一次性读取整个文件内容。推荐使用…

UGUI学习笔记之渲染顺序

转载请注明地址&#xff1a;http://www.cnblogs.com/Vincentblogs/p/4083028.html QQ群&#xff1a;346738352 Unity技术交流群&#xff0c;讲纯粹的技术。 数据记录为Unity4.6b21版本 图片解释&#xff1a;这是一个按钮UI,层级1显示的是按钮背景&#xff0c;层级2显示的Image…

exp导出excel oracle_如何从Oracle快速导出数据到Excel

【摘要】在生产系统使用过程中&#xff0c;常常会有从数据库中导出数据的需求。支持多种导出方式&#xff0c;例如使用spool、utl_file等内置方法导出&#xff0c;利用plsql developer、等第三方工具等。【正文】Oracle支持多种导出方式&#xff0c;包括自带的工具包和第三方工…

C#找出数组中重复次数最多的数值

给定一个int数组&#xff0c;里面存在重复的数值&#xff0c;如何找到重复次数最多的数值呢? 这是在某社区上有人提出的问题&#xff0c;我想到的解决方法是分组。 1、先对数组中的所有元素进行分组&#xff0c;那么&#xff0c;重复的数值肯定会被放到一组中&#xff1b; 2、…

什么比日期和时区更难? SQL / JDBC中的日期和时区!

在jOOQ邮件列表上&#xff0c;最近有一个有趣的讨论&#xff0c;关于jOOQ当前缺乏对TIMESTAMP WITH TIME ZONE数据类型的现成支持。 没有人说日期&#xff0c;时间和时区很容易&#xff01; 这里有一个有趣的部分&#xff0c;我建议阅读&#xff1a; 虚假的程序员相信时间 当…

Javascript – 正则表达式

目录 1. 正则表达式1.1 创建1.2 RegExp 对象属性1.3 RegExp 对象方法1.4 RegExp 分组2. 元字符和正则表达式规则1正则表达式 正则表达式本身就是一种语言&#xff0c;由普通字符和特殊的元字符&#xff08;metacharacters&#xff09;组成。它描述了字符串的匹配模式&#xff0…

spark-sql建表语句限制_第三篇|Spark SQL编程指南

在《第二篇|Spark Core编程指南》一文中&#xff0c;对Spark的核心模块进行了讲解。本文将讨论Spark的另外一个重要模块--Spark SQL&#xff0c;Spark SQL是在Shark的基础之上构建的&#xff0c;于2014年5月发布。从名称上可以看出&#xff0c;该模块是Spark提供的关系型操作AP…

4固定在底部_礼堂椅厂家教你如何固定座椅

礼堂椅厂家众所周知&#xff0c;当人们离开时&#xff0c;礼堂或刷房中使用的座椅会自动翻转到垂直位置&#xff0c;因此行和行之间有一条大通道让人走路。 在现有技术中&#xff0c;通过以下方法翻转礼堂椅&#xff1a;在两个支腿之间设置固定轴&#xff0c;并且在支座底部的两…

带有Hibernate OGM的NoSQL –第三部分:在WildFly上构建REST应用程序

欢迎回到我们的教程系列“带有Hibernate OGM的NoSQL”&#xff01; 感谢Gunnar Morling&#xff08; gunnarmorling &#xff09;创建了本教程。 在这一部分中&#xff0c;您将学习如何在WildFly服务器上运行的Java EE应用程序中使用Hibernate OGM。 使用本教程前面部分已经知道…

关于创业公司的一些事情

最近终于离职了&#xff0c;离开了这家呆了快两年的公司&#xff0c;其中酸甜苦辣&#xff0c;不足为外人道&#xff0c;仅此记录下一些想法&#xff0c;供自己与大家思考。本文只讨论加入创业公司&#xff0c;并不讨论自己创业或者成为合伙人。 0. 该不该加入创业公司 我刚从研…

python时间去掉t_Python的set集合详解

Python 还包含了一个数据类型 —— set &#xff08;集合&#xff09;。 集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。 集合对象还支持 union&#xff08;联合&#xff09;&#xff0c;intersection&#xff08;交&#xff09;&#xff0c;difference&…