GCD学习总结

GCD概述:

OC:

/*
 GCD:Grand Central Dispatch 牛X的中枢调度器,C语言编写
 GCD:自动管理线程的生命周期,(创建, 调度任务, 销毁线程)
 
 任务:block (1.定制任务)
 队列:queue (2.任务添加到队列)
 
GCD自动从队列queue中取出任务block执行,遵循FIFO原则,先进先出
 
任务block执行方式:
    同步的(synchronous ['sɪŋkrənəs]):不能开新线程
        dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);
    异步的(asynchronous [e'sɪŋkrənəs]):能开新线程
        dispatch_async(dispatch_queue_t queue, dispatch_block_t block);
 
 队列queue:
    并发队列(Concurrent Dispatch Queue):
        [DISPATCH_QUEUE_CONCURRENT];
        让多个任务并发执行,自动开启多个线程同时执行任务;
        该功能只在异步函数(dispatch_async)下有效;
    串行队列(Serial Dispatch Queue):
        [DISPATCH_QUEUE_SERIAL];
        让任务顺序执行;
 
 队列queue的创建:
    并发队列:
        方式1.dispatch_queue_create(const char *label, dispatch_queue_attr_a attr)
            label:表示该队列的名字(标识), C语言中的字符串,创建的时候直接"abcde";
            attr:表示队列属性,设置并发or串行,此处使用并发(DISPATCH_QUEUE_CONCURRENT)
        方式2:获取全局并发队列
            dispatch_get_global_queue(dispatch_queue_priority_t priority, unsigned long flags);
            priority:队列的优先级(高,默认,低,后台)
            flags:此参数暂时无用,用0即可
    串行队列:
        方式1.dispatch_queue_create(const char *label, dispatch_queue_attr_a attr)
            label:表示该队列的名字(标识);
            attr:表示队列属性,设置并发or串行,此处使用串行(DISPATCH_QUEUE_SERIAL or NULL)
        方式2:使用主队列,与主线程相关联的队列
            主队列是GCD自带的一种特殊的串行队列;该队列中的任务,都会在主线程中执行;
            dispatch_get_main_queue();
*/
相关练习:
#pragma mark - 并发队列,同步任务: 没有开启新线程,任务按添加顺序依次执行;
- (void)concurrentSync {
    // A.创建并发队列concurrentQueue:
    char *queueName = "ConcurrentQueue";
    dispatch_queue_t concurrentQueue = dispatch_queue_create(queueName, DISPATCH_QUEUE_CONCURRENT);
    
    // B.创建任务block
    // 方式一: 定义一个block类型,命名为TestBlock1,然后只用该类型声明变量block1
    // 1.定义一个block的类型,返回值void,参数为空,命名为Block1,(类似于 int),
    typedef void (^TestBlock1)();
    // 2.使用Block1类型定义一个变量block, 同时做赋值操作,赋值的内容为后面的代码段(^{...})
    TestBlock1 block1 = ^{
        // 这是里block中的操作
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    // 方式二: 直接定义一个名为block的block2变量
    void (^block2)() = ^{
        // 这是里block中的操作
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    
    // C.给并发队列concurrentQueue,添加同步任务dispatch_sync
    // 方式1: block1变量
    dispatch_sync(concurrentQueue, block1);
    // 方式2: block2变量
    dispatch_sync(concurrentQueue, block2);
    // 方式3: 直接添加block
    dispatch_sync(concurrentQueue, ^{
        // 这是里block中的操作
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block--3---%@", [NSThread currentThread]);
        }
    });
}

#pragma mark - 并发队列,异步任务: 开启新线程,任务并发执行
- (void)concurrentAsync {
    // 1.创建并发队列 DISPATCH_QUEUE_CONCURRENT
    char *queueName = "ConcurrentQueue";
    dispatch_queue_t concurrentQueue = dispatch_queue_create(queueName, DISPATCH_QUEUE_CONCURRENT);
    
    // 2.创建任务block
    typedef void (^TestBlock)();
    TestBlock block = ^{
        // 这是里block中的操作
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    void (^block2)() = ^{
        // 这是里block中的操作
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    // 3.并发队列concurrent,添加异步任务async;
    dispatch_async(concurrentQueue, block);
    dispatch_async(concurrentQueue, block2);
    dispatch_async(concurrentQueue, ^{
        // 这是里block中的操作
        for (int i = 0; i < 5; i++) {
            NSLog(@"---3---%@", [NSThread currentThread]);
        }
    });
    
}

#pragma mark - 全局队列,同步任务: 没有开启新线程,任务按添加顺序依次执行;
- (void)globalSync {
    //全局队列的优先级
#define DISPATCH_QUEUE_PRIORITY_HIGH 2
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
#define DISPATCH_QUEUE_PRIORITY_LOW (-2)
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
    typedef long dispatch_queue_priority_t;
    
    // 1.获取全局队列 DISPATCH_QUEUE_PRIORITY_DEFAULT or 0 都可以
    dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 2.创建任务block
    typedef void (^TestBlock1)();
    TestBlock1 block1 = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    void (^block2)() = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    
    // 3.给全局队列globalQueue,添加同步任务dispatch_sync
    dispatch_sync(globalQueue, block1);
    dispatch_sync(globalQueue, block2);
    dispatch_sync(globalQueue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block--3---%@", [NSThread currentThread]);
        }
    });
    
}
#pragma mark - 全局队列,异步任务: 开启新线程,任务并发执行;
- (void)globalAsync {
    // 1.获取全局队列 DISPATCH_QUEUE_PRIORITY_DEFAULT or 0 都可以
    dispatch_queue_t globalQueue = dispatch_get_global_queue(0, 0);
    // 2.创建任务
    typedef void (^TestBlock)();
    TestBlock block = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    void (^block2)() = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    // 3.全局队列globalQueue,添加异步任务;
    dispatch_async(globalQueue, block);
    dispatch_async(globalQueue, block2);
    dispatch_async(globalQueue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---3---%@", [NSThread currentThread]);
        }
    });
}

#pragma mark - 串行队列,同步任务: 没有开启新线程,任务按添加顺序依次执行;
- (void)serialSync {
    char *queueName = "SerialQueue";
    // 串行队列 DISPATCH_QUEUE_SERIAL or NULL
    dispatch_queue_t serialQueue = dispatch_queue_create(queueName, DISPATCH_QUEUE_SERIAL);
    
    // 创建任务block
    typedef void (^TestBlock1)();
    TestBlock1 block1 = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    void (^block2)() = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    
    // 给串行队列serialQueue,添加同步任务dispatch_sync
    dispatch_sync(serialQueue, block1);
    dispatch_sync(serialQueue, block2);
    dispatch_sync(serialQueue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block--3---%@", [NSThread currentThread]);
        }
    });
    
}

#pragma mark - 串行队列,异步任务: 开启新线程,任务按添加顺序依次执行;
- (void)serialAsync {
    // 1.创建队列queue
    char *queueName = "SerialQueue";
    dispatch_queue_t serialQueue = dispatch_queue_create(queueName, NULL);
    
    // 2.创建任务block
    typedef void (^TestBlock1)();
    TestBlock1 block1 = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    void (^block2)() = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    
    // 3.串行队列serialQueue, 添加异步任务
    dispatch_async(serialQueue, block1);
    dispatch_async(serialQueue, block2);
    dispatch_async(serialQueue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block--3---%@", [NSThread currentThread]);
        }
    });
}

#pragma mark - 主队列, 同步任务: 死锁
- (void)mainSync {
    NSLog(@"%s", "主队列mai zhuduilie, 同步任务sync tongburenwu, 会造成死锁 huizaochengsisuo");
    // 1.获得主队列main
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    
    // 2.创建任务block
    typedef void (^TestBlock1)();
    TestBlock1 block1 = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    void (^block2)() = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    
    // 3.给主队列mainQueue,添加同步任务dispatch_sync
    dispatch_sync(mainQueue, block1);
    dispatch_sync(mainQueue, block2);
    dispatch_sync(mainQueue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block--3---%@", [NSThread currentThread]);
        }
    });
    // 死锁导致block中的内容都不会执行
}

/*
 GCD Queue 分为三种:
 1,The main queue:主队列,主线程就是在个队列中。
 2,Global queues: 全局并发队列。
 3,用户队列:是用函数 dispatch_queue_create 创建的自定义队列
 
 dispatch_sync 和 dispatch_async 区别:
 dispatch_async(queue,block) async 异步队列,dispatch_async 函数会立即返回, block会在后台异步执行。
 dispatch_sync(queue,block) sync 同步队列,dispatch_sync 函数不会立即返回,及阻塞当前线程,等待block同步执行完成。
 
 分析:
 在主线程中,即dispatch_get_main_queue()中,执行到sync时向dispatch_get_main_queue()插入同步block1.
 sync会等到后面block1执行完成才返回,sync又在dispatch_get_main_queue() 队列中,它是串行队列,sync是后加入的,
 前一个是主线程,所以sync想执行block必须等待主线程执行完成,主线程等待sync返回,去执行后续内容。
 造成死锁,sync等待main执行完成,mian等待sync函数返回。
 */

#pragma mark - 主队列,异步任务: 没有开启新线程,任务按添加顺序依次执行;
- (void)mainAsync {
    // 1.获取主队列main
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    // 2.创建任务block
    typedef void (^TestBlock1)();
    TestBlock1 block1 = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block1---%@", [NSThread currentThread]);
        }
    };
    void (^block2)() = ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block2---%@", [NSThread currentThread]);
        }
    };
    
    // 3.给主队列mainQueue,添加异步任务dispatch_async
    dispatch_async(mainQueue, block1);
    dispatch_async(mainQueue, block2);
    dispatch_async(mainQueue, ^{
        for (int i = 0; i < 5; i++) {
            NSLog(@"---block--3---%@", [NSThread currentThread]);
        }
    });
}

#pragma mark -
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    /***********************************************************/
    // 定义block的两种方式之一:
    // 定义
    // 参考范例,返回值int,参数(int, int)(没有参数名,匿名),名称Test
    typedef int (^Test1)(int, int);
    // 使用Test初始化一个变量test
    Test1 test1 ;
    // 实现
    test1 = ^(int x, int y) {
        return  x + y;
    };
    // 调用
    int result = test1(1, 2); //result = 3;
    NSLog(@"%d", result);
    
    /////////
    
    // 初始化变量,实现,同时进行
    Test1 test = ^(int x, int y) {
        return  x + y;
    };
    // 调用
    NSLog(@"%d", test(100, 200));
    
    /***********************************************************/
    // 定义block的两种方式之二:
    // 定义,实现,合并进行
    // 直接定义一个变量test2,参数(int, int)(没有参数名,匿名),名称Test
    int (^test2)(int, int) = ^(int x, int y){
        return x + y;
    };
    NSLog(@"%d", test2(10, 20)); //result = 30;
    /***********************************************************/
}

Swift 3.0:

/**
 GCD:Grand Central Dispatch 牛X的中枢调度器
 GCD:自动管理线程的生命周期,(创建, 调度任务, 销毁线程)
 
 任务:闭包closure or DispatchWorkItem
 队列:DispatchQueue
 
 GCD自动从队列中取出任务执行,遵循FIFO原则,先进先出
 
 任务执行方式:
    同步(synchronous ['sɪŋkrənəs]):不能开新线程
        DispatchQueue.global().sync {
            // 同步执行
        }
    异步(asynchronous [e'sɪŋkrənəs]):能开新线程
        DispatchQueue.global().async {
            // code
            DispatchQueue.main.async {
                // 主线程中
            }
        }
 
 队列DispatchQueue:
    DispatchQueue的默认初始化方法创建的就是一个串行队列,如果要创建并发的队列,在attributes中声明concurrent。
    label:表示该队列的名字(标识);
    attributes:表示队列属性,默认为串行,
    同步队列
        let serialQueue = DispatchQueue(label: "QueueName")
        让任务顺序执行;
    主队列
        let mainQueue = DispatchQueue.main
 
    并发队列
        let concurrentQueue = DispatchQueue(label: "QueueName", attributes: .concurrent)
        让多个任务并发执行,自动开启多个线程同时执行任务;
    全局并发队列
        let globalQueue = DispatchQueue.global(qos: .default)
        let globalQueue = DispatchQueue.global()
        // global 有默认的参数default, 如需改变优先级,则输入对应的枚举即可
 
 */
相关练习:
    // MARK: - 并发Concurrent,同步sync,没有开启新线程,任务在主队列main依次执行;
    func concurrentSync() -> Void {
        // 创建并发队列
        let concurrentQueue = DispatchQueue(label: "ConcurrentQueue", attributes: .concurrent)
        
        // 任务类型
        typealias Task = () -> Void
        // Task类型的变量
        let task1: Task
        // 任务实现
        task1 = {
            print("concurrentSync task1...", Thread.current)
        }
        
        let task2: () -> Void = {
            print("concurrentSync task2...", Thread.current)
        }
        
        // 并发队列Concurrent,同步sync执行
        concurrentQueue.sync(execute: task1) // main
        concurrentQueue.sync(execute: task2) // main
        concurrentQueue.sync {
            print("concurrentSync task3...", Thread.current)
        } // main
    }
    
    // MARK: - 并发Concurrent,异步async,开启新线程,任务并发执行;
    func concurrentAsync() -> Void {
        // 队列(并发concurrent)
        let concurrentQueue = DispatchQueue(label: "ConcurrentQueue", attributes: .concurrent)
        // 任务(闭包 or block)
        typealias Task = () -> Void
        let task1: Task = {
            print("concurrentAsync-task1...", Thread.current)
        }
        let task2: () -> Void = {
            print("concurrentAsync-task2...", Thread.current)
        }
        // 并发,异步
        concurrentQueue.async(execute: task1) // new 1
        concurrentQueue.async(execute: task2) // new 2
        concurrentQueue.async {
            print("concurrentAsync-task3...", Thread.current)
        } // new 3
    }
    
    // MARK: - 全局global,同步sync,没有开启新线程,任务在主队列main依次执行;
    func globalSync() -> Void {
        typealias Task = () -> Void
        let task1: Task = {
            print("globalSync...task1...", Thread.current)
        }
        let task2: () -> Void = {
            print("globalSync...task2...", Thread.current)
        }
        
        /**
         * global优先级的新旧枚举值对应
         * DISPATCH_QUEUE_PRIORITY_HIGH:         .userInitiated
         * DISPATCH_QUEUE_PRIORITY_DEFAULT:      .default
         * DISPATCH_QUEUE_PRIORITY_LOW:          .utility
         * DISPATCH_QUEUE_PRIORITY_BACKGROUND:   .background
         */
        // public class func global(qos: DispatchQoS.QoSClass = default) -> DispatchQueue
        // global 有默认的参数default, 如需改变优先级,则输入对应的枚举即可
        DispatchQueue.global(qos: .userInteractive).sync(execute: task1) // main 1
        DispatchQueue.global(qos: .userInteractive).sync(execute: task2) // main 2
        DispatchQueue.global(qos: .userInteractive).sync {
            print("globalSync...task3...", Thread.current)
            
        } // main 3
    }
    
    // MARK: - 全局global,异步async,开启新线程,任务并发执行;
    func globalAsync() -> Void {
        typealias Task = () -> Void
        let task1: Task = {
            print("globalAsync...task1...", Thread.current)
        }
        let task2: Task = {
            print("globalAsync...task2...", Thread.current)
        }
        DispatchQueue.global().async(execute: task1) // new 1
        DispatchQueue.global().async(execute: task2) // new 2
        DispatchQueue.global().async {
            print("globalAsync...task3...", Thread.current)
        } // new 3
    }
    
    /// 线程任务
    typealias ThreadTask = () -> Void

    // MARK: - 串行serial,同步sync,没有开启新线程,任务按顺序执行;
    func serialSync() -> Void {
        // 队列
        let serialQueue = DispatchQueue(label: "SerialQueue")
        // 任务
        let task1: ThreadTask = {
            print("serialSync...task1...", Thread.current)
        }
        let task2: ThreadTask = {
            print("serialSync...task2...", Thread.current)
        }
        let task3: ThreadTask = {
            print("serialSync...task3...", Thread.current)
        }
        // 串行,同步
        serialQueue.sync(execute: task1) // main 1
        serialQueue.sync(execute: task2) // main 2
        serialQueue.sync(execute: task3) // main 3
    }
    
    // MARK: - 串行Serial,异步async,开启新线程,任务按顺序执行
    func serialAsync() -> Void {
        // 队列
        let serialQueue = DispatchQueue(label: "SerialQueue")
        // 任务
        let task1: ThreadTask = {
            print("serialSync...task1...", Thread.current)
        }
        let task2: ThreadTask = {
            print("serialSync...task2...", Thread.current)
        }
        let task3: ThreadTask = {
            print("serialSync...task3...", Thread.current)
        }
        // 串行,异步
        serialQueue.async(execute: task1) // new 1
        serialQueue.async(execute: task2) // new 2
        serialQueue.async(execute: task3) // new 3
    }
    
    // MARK: - 主队列main,同步sync,死锁
    func mainSync() -> Void {
        // 队列
        let mainQueue = DispatchQueue.main
        // 任务
        let task1: ThreadTask = {
            print("serialSync...task1...", Thread.current)
        }
        let task2: ThreadTask = {
            print("serialSync...task2...", Thread.current)
        }
        let task3: ThreadTask = {
            print("serialSync...task3...", Thread.current)
        }
        // 主队列,同步
        mainQueue.sync(execute: task1) // 死锁 x
        mainQueue.sync(execute: task2) // x
        DispatchQueue.main.sync(execute: task3) // x
    }
    
    // MARK: - 主队列main,异步async,不开启新线程,任务依次执行
    func mainAsync() -> Void {
        let mainQueue = DispatchQueue.main
        
        let task1: ThreadTask = {
            print("serialSync...task1...", Thread.current)
        }
        let task2: ThreadTask = {
            print("serialSync...task2...", Thread.current)
        }
        let task3: ThreadTask = {
            print("serialSync...task3...", Thread.current)
        }
        
        mainQueue.async(execute: task1) // main 1
        mainQueue.async(execute: task2) // main 2
        DispatchQueue.main.async(execute: task3) // main 3
    }
    
    // MARK: - 闭包测试
    func closureTest() -> Void {
        // 闭包回顾
        /***********************************************************/
        // 定义, 有3+参, 有返回值
        typealias Test = (Int, Int, Int) -> Int
        // 声明变量test1
        var test1: Test
        // 实现
        test1 = { x, y, z in
            // 闭包中的操作
            print("有3+参, 有返回值 test1...111")
            return x + y + z
        }
        // 调用
        print("test1...", test1(1, 2, 3))
        
        // 声明,实现
        let test2: Test = {
            // 闭包中的操作
            print("有3+参, 有返回值 test2...222")
            return $0 + $1 + $2
        }
        // 调用
        print("test2...", test2(10, 20, 30))
        /***********************************************************/
        // 定义, 有2参, 有返回值
        var test3: (Int, Int) -> Int
        // 实现
        test3 = (+)
        // 调用
        print("有2参, 有返回值 test3...", test3(100, 200))
        /***********************************************************/
        // 定义,无参,有返回值
        var test4: () -> Int
        // 实现
        test4 = {
            // 闭包中的操作
            print("无参,有返回值 test4... 444")
            return 12345
        }
        // 调用
        print("test4...", test4())
        /***********************************************************/
        // 定义,无参,无返回值
        let test5: () -> Void = {
            // 相关操作
            print("无参,有返回值 test5... 555")
        }
        test5()
        /***********************************************************/
    }

参考资料:
http://www.jianshu.com/p/fc78dab5736f
http://www.jianshu.com/p/28044b17f94b
https://www.logcg.com/archives/2040.html
https://github.com/future-challenger/Swift3.0/blob/master/GCD/README.md
https://my.oschina.net/doxing/blog/618132
http://v.youku.com/v_show/id_XMTU5MDg1MTE0NA==.html
http://v.youku.com/v_show/id_XMTU5MDg0OTY1Mg==.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • GCD GCD的全称是Grand Central Dispatch,字面意思就是“极好的中枢调度器”,它能通过队列...
    cr7aa阅读 470评论 0 0
  • 1、前言 GCD的学习中一定要理解任务,同步、异步,串行、并发的概念,以及他们之间相互结合运行的效果。 2、GCD...
    SuperDawn_0828阅读 367评论 0 1
  • 许久许久未见的人 原来真的梦不到 孤独 和谁的相处都无法避免 可能就是某个时刻的无解和凉意 这很平常呀 所以不 过...
    写在沙上阅读 223评论 0 0
  • Eimon阅读 178评论 0 0
  • 再见你时,一如从前的模样。光洁的额头,姣好的面容,笑时露出一排整齐的牙齿。和年少时分毫未变。 走进你的房...
    土lemon阅读 676评论 0 2