GCD

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了GCD相关的知识,希望对你有一定的参考价值。

---恢复内容开始---

一. 简介

  纯C语言

二.优势

  1. 自动利用更多的CPU内核
  2. 自动管理线程的生命周期(创建/调度/销毁)
  3. 不需要编写线程管理代码

三.使用步骤

  1. 定制任务
  2. 将任务添加到队列中
  3. GCD自动取出队列中任务,放到对应的线程中执行(任务的执行遵循FIFO)

四.GCD的几种操作

  1. 开启异步线程,并发执行,执行完毕后回到主线程更新UI

 

1 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
2 dispatch_async(queue, ^{
3         // 任务1
4         // 任务2
5         dispatch_async(dispatch_get_main_queue(), ^{
6             // 更新UI操作
7         });
8 });

 

---恢复内容结束---

  在queue中,所有的线程都与主线程不相同,且它们互不相同,即后台开了不止一条线程

 

  2.开启异步线程,串行,执行完毕后回到主线程更新UI

1 dispatch_queue_t queue = dispatch_queue_create("queueName", NULL);
2     dispatch_async(queue, ^{
3         // 任务1
4         // 任务2
5         dispatch_async(dispatch_get_main_queue(), ^{
6             // 更新UI操作
7         })
8     });

  此时,queue中只在后台开一条线程

  

  3.分派组

    NSLog(@"first-----%@",[NSThread currentThread]);
    // 获取全局并发队列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    // 在全局并发队列中执行任务
    dispatch_async(queue, ^{
    NSLog(@"second-----%@",[NSThread currentThread]);
        NSLog(@"开始执行异步线程");
        NSDate* startTime = [NSDate date];
        // 下面两个操作为 模拟的耗时操作
        NSString* fetchStr = [self fetchSomethingFromServer];
        NSString* processData = [self processData:fetchStr];
        
        // 开启一个分派组
        dispatch_group_t group = dispatch_group_create();
        // 放到分派组中
        __block NSString* firstStr = nil;
        __block NSString* secondStr = nil;
        // 将可以并发执行的任务放到分派组中
        dispatch_group_async(group, queue, ^{
            firstStr = [self calculatorFirstResult:processData];
        });
        dispatch_group_async(group, queue, ^{
            secondStr = [self calculatorSecondResult:processData];
        });
        // 分派组完成后执行
        dispatch_group_notify(group, queue, ^{
            NSDate* endTime = [NSDate date];
            NSLog(@"--%f--",[endTime timeIntervalSinceDate:startTime]);
        });
    });

 

五.GCD的几种方法

  1. 延时操作
    1 [NSThread sleepForTimeInterval:3];

  上面这个方法会阻塞当前线程

  2.延时操作

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        // 操作
    });

  这个方法不会阻塞当前线程,仅仅将任务操作延时执行

  3.一次性代码

static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 操作
    });

  被这段代码块锁定的代码 只能只能一次

 

六.GCD单例模式写法(ARC)

//.h
+ (instancetype)sharedDataTool;
//.m
static id _instance;

+ (instancetype)sharedDataTool{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[self alloc]init];
    });
    return _instance;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

- (id)copyWithZone:(NSZone *)zone{
    return _instance;
}

 

以上是关于GCD的主要内容,如果未能解决你的问题,请参考以下文章

代码笔记iOS-GCD用法

我写的由 GCD 代码支持的读写器锁导致并行测试中的死锁

swiftBlockOperation和GCD实用代码块

iOS多线程GCD详解

GCD的常用代码块

GCD