你的位置:首页 > 操作系统

[操作系统]ios开发:GCD多线程


   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 Queuedispatch_queue_t mainDispatchQueue = dispatch_get_main_queue();// 获取Global Dispatch Queuedispatch_queue_t globalDispatchQueueDefault = 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(@"线程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个线程都执行完成后,更新操作才执行

 

 3、dispatch_barrier_async

  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");  });