美文网首页iOS开发超神学院iOS技术文章
iOS中 GCD-Grand Central Dispath

iOS中 GCD-Grand Central Dispath

作者: LeaderBiao | 来源:发表于2016-06-25 17:21 被阅读54次

    版权声明:本文为博主原创文章,未经博主允许不得转载。

    GCD:Grand Central Dispath "牛逼的中枢调度器";是纯C语言编写的,提供了很多比较强大的函数.

    GCD:优势

    1.目前是苹果主推的线程管理方式
    2.它会自动的利用更多的CPU资源(双核,四核)
    3.它会自动的管理线程的生命周期(线程的创建/调度/销毁);
    4.程序员只需要告诉GCD自己想要执行的哪些任务,不需要写一行线程管理的代码

    #import "ViewController.h"
    
    #define kURLString1 @"http://www.nbsheji.cn/uploadfiles/2010113143922418.jpg"
    
    #define kURLString2 @"http://amuse.nen.com.cn/imagelist/11/21/9as70n3ir61b.jpg"
    
    @interface ViewController ()
    
    @property (retain, nonatomic) IBOutlet UIImageView *FirstView;//第一个图片
    
    @property (retain, nonatomic) IBOutlet UIImageView *secondView;//第二个图片
    
    @property(nonatomic,retain)NSMutableArray *dataSource;//存储请求下来的数据
    
    @end
    
    @implementation ViewController
    
    //懒加载
    
    - (NSMutableArray *)dataSource
    {
      if (_dataSource == nil) 
      {
        self.dataSource = [NSMutableArray arrayWithCapacity:0];
      }
    return [[_dataSource retain]autorelease];
    }```
    

    1.串行队列:(线程同步)添加到这个队列的任务一个接一个的执行(一个任务完成,才再去完成另一个任务)

    • (IBAction)handleSerialQueue:(UIButton *)sender
      {
      //获取系统串行队列

    // (1)向系统的创建的串行队列中添加异步任务,还是在主线程中完成;

    // (2)向系统创建的串行队列中添加同步任务,会造成线程死锁,导致其他人无法执行;

    dispatch_queue_t queue1 = dispatch_get_main_queue();

    //01:队列的唯一标识,采用反域名形式

    //02:队列的属性类型,也就是标识这个队列是串行队列还是并行队列

    // (1)自己创建的串行队列中添加异步任务是在子线程中完成任务;

    // (2)自己创建的串行队列中添加同步任务是在主线程中完成任务;

    dispatch_queue_t queue2 = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_SERIAL);

    /*

    //异步任务

    //第一个参数:任务添加到队列名称

    //第二个参数:block执行任务内容

    dispatch_async(queue2, ^{

    NSLog(@"任务1 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

    });

    dispatch_async(queue2, ^{

    NSLog(@"任务2 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

    });

    dispatch_async(queue2, ^{

    NSLog(@"任务3 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

    });

    //释放掉自己的创建的队列,出现create就要释放

    dispatch_release(queue2);

    */

    //同步任务

    dispatch_sync(queue2, ^{

    NSLog(@"任务1 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

    });

    dispatch_sync(queue2, ^{

    NSLog(@"任务2 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

    });

    dispatch_sync(queue2, ^{

    NSLog(@"任务3 %@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);

    });

    // 总结:同步任务:不管在哪一个队列中都是主线程中执行,但是不能将其添加到系统自带的串行队列中;

    // 异步任务:在自己创建的串行队列中,在子线程中执行,如果是系统创建的队列在主线程中执行;

    }```

    2.并行队列 (线程并发) 添加到此队列的任务同时执行  假象.
    - (IBAction)handleConcurrentQueue:(UIButton *)sender 
    {
    //1.获取系统自带的并行队列
    
    //01.队列的优先级
    
    //02.预留参数  给0
    
    dispatch_queue_t queue1 = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //2.自己创建并行队列 (一般不自己创建并行队列,系统的并行队列已经够用了)
    
    dispatch_queue_t queue2 = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_CONCURRENT);
    
    //同步任务
    
    dispatch_sync(queue1, ^{
    
    NSLog(@"同步任务%@  %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
    
    });
    
    //异步任务
    
    dispatch_async(queue2, ^{
    
    NSLog(@"任务1%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
    
    });
    
    dispatch_async(queue2, ^{
    
    NSLog(@"任务2%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
    
    });
    
    dispatch_async(queue2, ^{
    
    NSLog(@"任务3%@ %d",[NSThread currentThread],[NSThread currentThread].isMainThread);
    
    //线程间的通信
    
    //由子线程回到主线程
    
    //获取系统的串行队列
    
    dispatch_async(dispatch_get_main_queue(), ^{
    
    NSLog(@"我回到主线程了");
    
    });
    
    });
    
    //释放出现create就要释放
    
    dispatch_release(queue2);
    
    }```
    

    3.分组队列:把多个任务添加到一个分组中执行,此时会在所有的任务完成后会自动发一个通
    知,dispatch_group_notifity接收这个消息,然后在所有任务完成之后处理.

    • (IBAction)handleGroupQueue:(UIButton *)sender {

    //1.创建并行队列,并执行任务

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    __block typeof(self)weakSelf = self;

    //创建分组异步同步任务

    dispatch_group_t group = dispatch_group_create();

    //01.分组名

    //02.要添加的队列名

    //03.要执行的任务

    dispatch_group_async(group, queue, ^{

    NSURL *urlString = [NSURL URLWithString:kURLString1];

    NSData *data1 = [NSData dataWithContentsOfURL:urlString];

    //使用数组存放请求下来的数据

    [weakSelf.dataSource addObject:data1];

    });

    dispatch_group_async(group, queue, ^{

    NSURL *url = [NSURL URLWithString:kURLString2];

    NSData *data2 = [NSData dataWithContentsOfURL:url];

    [weakSelf.dataSource addObject:data2];

    });

    //分组中的任务都完成后会自动触发下面的方法

    dispatch_group_notify(group, queue, ^{

    weakSelf.FirstView.image = [UIImage imageWithData:weakSelf.dataSource[0]];

    weakSelf.secondView.image = [UIImage imageWithData:weakSelf.dataSource[1]];

    });

    //释放分组

    dispatch_release(group);

    }```

    4.障碍队列
    - (IBAction)handleBarrierQueue:(UIButton *)sender {
    
    //1.使用障碍队列只能使用自己创建的并列队列,不能使用系统的并行队列
    
    dispatch_queue_t  queue = dispatch_queue_create("com.xcqnzf.xuchang", DISPATCH_QUEUE_CONCURRENT);
    
    //2.往并行队列中添加任务
    
    dispatch_async(queue, ^{
    
    NSLog(@"A写入文件");
    
    });
    
    dispatch_async(queue, ^{
    
    NSLog(@"B写入文件");
    
    });
    
    dispatch_async(queue, ^{
    
    NSLog(@"C写入文件");
    
    });
    
    //添加障碍,间隔写入和读取的任务,障碍任务之前的任务都完成了才能继续完成障碍任务后面的任务
    
    dispatch_barrier_async(queue, ^{
    
    NSLog(@"我是障碍任务,读取的任务先等会");
    
    });
    
    dispatch_async(queue, ^{
    
    NSLog(@"D读取文件");
    
    });
    
    dispatch_async(queue, ^{
    
    NSLog(@"D读取文件");
    
    });
    
    dispatch_async(queue, ^{
    
    NSLog(@"E读取文件");
    
    });
    
    //3.释放
    
    dispatch_release(queue);
    
    }
    
    只执行一次
    - (IBAction)handleOnce:(UIButton *)sender {
    
    static  dispatch_once_t oneToken ;
    
    //
    
    dispatch_once(&oneToken, ^{
    
    NSLog(@"有能耐让我走两次");
    
    });
    
    }
    
    这里需要写一个单例
    
    Helper.h
    
    @interface Helper : NSObject
    
    + (Helper *)shareHelper;
    
    @end
    
    Helper.h
    
    @implementation Helper
    
    static  Helper *helper = nil;
    
    + (Helper *)shareHelper{
    
    //VIP
    
    static dispatch_once_t oneToken;
    
    dispatch_once(&oneToken, ^{
    
    helper = [[Helper alloc]init];
    
    });
    
    return helper;
    
    }
    
    @end
    
    重复任务
    - (IBAction)handleRepeat:(UIButton *)sender {
    
    //1.获取系统的并行队列
    
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //2.向队列中添加重复任务
    
    //01.任务重复的次数
    
    //02.任务添加到的队列名称
    
    //03.当前是第几次重复这个任务
    
    dispatch_apply(10, queue, ^(size_t times) {
    
    NSLog(@"我要吃爆米花,这是我第%ld吃",times);
    
    });
    
    }
    
    延迟任务 一个任务要执行的时候先等上一段时间再做
    - (IBAction)handlePing:(UIButton *)sender {      //创建一个延迟任务      
    
    //01. DISPATCH_TIME_NOW 表示从当前时间开始     
    
     //02. 表示过多少秒才去执行任务    
    
      //03. 串行的主队列 
    
         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(55 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{          NSLog(@"延迟任务在主线程中执行");      });  
    
    }```

    相关文章

      网友评论

        本文标题: iOS中 GCD-Grand Central Dispath

        本文链接:https://www.haomeiwen.com/subject/wdjadttx.html