ios有三种多线程编程技术,分别是NSThread,Cocoa NSOperation和GCD,GCD全称Grand Central Dispatch 是Apple开发的一个多核编程的解决方法,在iOS4.0开始之后才能使用。GCD是一个可以替代NSThread, NSOperationQueue, NSInvocationOperation等技术的很高效和强大的技术,而且其使用起来比前两者更加的简单方便,今天主要给大家介绍一下有关GCD的使用。
GCD的工作原理是:让程序平行排队的特定任务,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务。一个任务可以是一个函数或者是一个语句块(block),GCD的依然是用线程实现,不过这样可以让普通开发者不用去关注其实现的细节,GCD中的队列称为dispatch queue。
Dispatch Queue分为三种:
1. Serial Dispatch Queue: 线性执行的线程队列,遵循FIFO(First In First Out)原则;
2. Concurrent Dispatch Queue: 并发执行的线程队列,并发执行的处理数取决于当前状态;
3. Main Dispatch Queue:在应用程序主线程上执行任务。
先来看几个常用的方法:
1.dispatch_async
有的时候避免界面在处理耗时的操作时卡死,比如发起网络请求,下载数据,缓存图片等,我们需要在另外的一个线程中处理这些操作,在这些操作完成后再通知主线程更新界面,看下面一段代码
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //耗时操作 NSDate* date = [NSDate date]; NSLog(@"------%@",date); NSURL * url = [NSURL URLWithString:@"http://d.hiphotos.baidu.com/image/pic/item/0823dd54564e9258ca2f34e79e82d158ccbf4e9b.jpg"]; NSData * data = [[NSData alloc]initWithContentsOfURL:url]; UIImage *image = [[UIImage alloc]initWithData:data]; [NSThread sleepForTimeInterval:4];//为了体现多线程的特点 在这里设置一个延时 if (data != nil) { dispatch_async(dispatch_get_main_queue(), ^{ //结果处理 UIImageView* imageview = [[UIImageView alloc]initWithImage:image]; imageview.frame = [UIScreen mainScreen].bounds; [self.view addSubview:imageview]; NSDate* date = [NSDate date]; NSLog(@"------%@",date); }); } });
我们在一个线程里完成下载图片的动作(为了体现多线程的作用,我们在这里设置一个延时)然后在另一个线程里把图片显示出来,来看一下运行结果。
系统给每个应用都提供的有队列,所以一般不用我们手动的去创建,我们只需要通过函数去获取队列就可以了
// 获取Main Dispatch Queue dispatch_queue_t mainDispatchQueue = dispatch_get_main_queue(); // 获取Global Dispatch Queue dispatch_queue_t globalDispatchQueueDefault = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
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(@"线程1"); }); dispatch_group_async(group, queue, ^{ [NSThread sleepForTimeInterval:5]; NSLog(@"线程2"); }); dispatch_group_async(group, queue, ^{ [NSThread sleepForTimeInterval:3]; NSLog(@"线程3"); });
//dispatch_group_notify函数用来指定一个额外的block,该block将在group中所有任务完成后执行 dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"更新操作"); });
由结果可以看出,3个线程都执行完成后,更新操作才执行
dispatch_barrier_async是在前面的任务执行结束后才执行,而且它后面的任务等它执行完成之后才会执行
dispatch_queue_t queue = dispatch_queue_create("gcdtest2", DISPATCH_QUEUE_CONCURRENT); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:1]; NSLog(@"线程1"); }); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:5]; NSLog(@"线程2"); }); dispatch_barrier_async(queue, ^{ NSLog(@"barrier执行"); [NSThread sleepForTimeInterval:5]; }); dispatch_async(queue, ^{ [NSThread sleepForTimeInterval:1]; NSLog(@"线程4"); });