IOS开发(62)之GCD上异步执行非UI任务
1 前言
如果想要在 GCD 的帮助下能够异步执行 Non-UI 相关任务。在主队列、串行队列和并发队列上异步执行代码块才能见识到 GCD 的真正实力。
要在分派队列上执行异步任务,你必须使用下面这些函数中的其中一个:
dispatch_async
为了异步执行向分派队列提交一个 Block Object(2 个都通过函数指定);
eg:dispatch_sync(concurrentQueue, printFrom1To1000);
dispatch_async_f
为了异步执行向分派队列提交一个 C 函数和一个上下文引用(3 项通过函数指定) 。
eg:dispatch_sync_f(concurrentQueue,NULL,printFrom1To1000);
2 代码实例
这节代码有点多,所以分了两个工程
First:ZYViewController.m
- (void) viewDidAppear:(BOOL)paramAnimated{ //新建一个队列 dispatch_queue_t concurrentQueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //执行concurrentQueue队列 dispatch_async(concurrentQueue, ^{ __block UIImage *image = nil; dispatch_sync(concurrentQueue, ^{ /*下载图片*/ /* 声明图片的路径*/ NSString *urlAsString = @"http://images.apple.com/mobileme/features/images/ipad_findyouripad_20100518.jpg"; //转换为NSURL对象 NSURL *url = [NSURL URLWithString:urlAsString]; NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url]; //声明NSError对象:一个NSError对象封装错误信息更丰富、更具可扩展性可以只使用一个错误代码和错误字符串。 NSError *downloadError = nil; //获得对应的Url返回的数据(这里是一个图片的数据) NSData *imageData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:&downloadError]; if (downloadError == nil &&imageData != nil){ //将NSData转换为图片 image = [UIImage imageWithData:imageData]; /* We have the image. We can use it now */ } else if (downloadError != nil){ NSLog(@"Error happened = %@", downloadError); }else{ NSLog(@"No data could get downloaded from the URL."); } }); dispatch_sync(dispatch_get_main_queue(), ^{ /* 在主线程里面显示图片*/ if (image != nil){ /* 穿件UIImageView视图 */ UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds]; /* 设置Image */ [imageView setImage:image]; /* 内容适应视图的大小通过保持长宽比*/ [imageView setContentMode:UIViewContentModeScaleAspectFit]; /* 想Controller View添加图像视图 */ [self.view addSubview:imageView]; } else { NSLog(@"Image isn't downloaded. Nothing to display."); } }); }); }
运行结果
Second:
ZYViewController.h
#import <UIKit/UIKit.h> @interface ZYViewController : UIViewController @property(nonatomic,strong) UILabel *myLabel; @end
ZYViewController.m
@synthesize myLabel; - (void)viewDidLoad { [super viewDidLoad]; //声明一个队列 dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); /* 如果我们还没有保存1000个随机数在磁盘上,下面的队列就用来生成这个文件并且用一个Array存放在磁盘上 */ dispatch_async(concurrentQueue, ^{ NSUInteger numberOfValuesRequired = 10000; //判断文件是否存在 if ([self hasFileAlreadyBeenCreated]== NO){ dispatch_sync(concurrentQueue, ^{ //声明一个可变数组用来存放数值 NSMutableArray *arrayOfRandomNumbers =[[NSMutableArray alloc] initWithCapacity:numberOfValuesRequired]; NSUInteger counter = 0; for (counter = 0;counter < numberOfValuesRequired;counter++){ //获得随机数 unsigned int randomNumber =arc4random() % ((unsigned int)RAND_MAX + 1); [arrayOfRandomNumbers addObject:[NSNumber numberWithUnsignedInt:randomNumber]]; } //将这个array写入到磁盘上 [arrayOfRandomNumbers writeToFile:[self fileLocation] atomically:YES]; }); } //存放读取文件内容的数组 __block NSMutableArray *randomNumbers = nil; //从磁盘上读取文件并升序排列 dispatch_sync(concurrentQueue, ^{ //如果文件已经被创建,读取他 if ([self hasFileAlreadyBeenCreated]){ randomNumbers = [[NSMutableArray alloc] initWithContentsOfFile:[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){ /* 刷新主线程 */ CGRect labelFrame = CGRectMake(0.0f, 0.0f, 300.0f, 200.0f); self.myLabel = [[UILabel alloc] initWithFrame:labelFrame]; self.myLabel.numberOfLines = 10;//分10行 NSString *str = [[NSString alloc] initWithFormat:@"RandomNumbers is %@",randomNumbers];//方法一 self.myLabel.text = str;//label的文字 self.myLabel.font = [UIFont boldSystemFontOfSize:14.0f];//字体样式 self.myLabel.center = self.view.center;//UILabel控件居中 [self.view addSubview:self.myLabel]; } }); }); } //获得文件路径 -(NSString *)fileLocation{ /* 创建一个列表的目录搜索路径。 NSDocumentDirectory:文档目录。 NSUserDomainMask:用户的主目录的地方,存放用户的个人项目。 */ NSArray *folders = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,NSUserDomainMask, YES); /* 如果没有找到返回空 */ if ([folders count] == 0) {return nil; } /* 获得文件路径的字符串形式 */ NSString *documentsFolder = [folders objectAtIndex:0]; //将文件名追加到foldser后面 return [documentsFolder stringByAppendingPathComponent:@"list.txt"]; } //判断文件是否被存在 - (BOOL) hasFileAlreadyBeenCreated{ BOOL result = NO; //初始化NSFileManager文件管理对象 NSFileManager *fileManager = [[NSFileManager alloc] init]; //判断文件是否存在 if ([fileManager fileExistsAtPath:[self fileLocation]]) { result = YES; } return result; }
运行结果
3 结语
以上是所有内容,希望对大家有所帮助。
Demo代码下载:http://download.csdn.net/detail/u010013695/5353320
Demo2代码下载:http://download.csdn.net/detail/u010013695/5353326