GCD

作者: tushizhan | 来源:发表于2016-12-26 15:25 被阅读0次

锁对象:锁对象必须是全局的,还要继承于NSObject;
互斥锁使用线程同步技术;
任务 :决定的是执行的方式,在哪里执行,是在当前的线程执行,还是再开辟一条线程执行;
队列: 决定的是任务的调度方式;决定的是任务怎么执行,是按照顺序还是不按照顺序

GCD:grand central dispatch是苹果公司为多核并行运算提出的方案;自动利用更多的cpu内核,自动管理线程的生命周期
核心:将任务添加到队列; 任务:执行什么操作,一般是block代码,队列:相当于容器,用来存放任务;
步骤:创建队列,创建任务 (确定要做的事情),添加任务到队列;GCD会自动的将队列中的任务取出来,放到对应的线程中执行;
队列的特点:先进先出(FIFO);
NSThread的任务封装在”方法中”;GCD的任务封装在”BLOCK”中;

BLOCK :属于C语言框架
是一种数据类型数据类型 :void (^) ( )
变量名 :void (^myBlock) ( )
赋值 :void (^myBlock) () = ^{ };

是一段代码块,被调用的时候才会执行 (类似于函数和方法);
可以定义为临时变量
可以定义函数
可以定义成属性
本质是函数指针;

block内存arc环境下,定义的单纯的block存储在全局区; <NSGlobalBlock>
访问外部变量,block储存在堆区;访问之前,变量在栈区; 0x7fff
访问时,变量被block拷贝到堆区 0x7fe
访问结束,变量的地址又回到栈区;

修改外部变量:block内部不能修改外部变量,如果修改的话,将外部变量用__Block修饰;
修改之前,变量地址在栈区,在block外面,用__block修饰了,地址不会变
修改时,变量地址跑到了堆区;
修改完成后,变量的地址回不到栈区了,留在了堆区;

MAR下:定义的单纯的block存储在全局区; <NSGlobalBlock>
访问外部变量:访问之前,栈区;
访问时,依然在栈区
访问之后,栈区,但是地址变了,内存空间没有变;

修改外部变量:修改之前,栈区
修改,栈区
修改之后,栈区,而且地址没有变;

block作为属性,MRC要用copy修饰 (ARC下strong也可以),因为要全局共享,所以放在了堆区.

GCD- (void)GCDDemo1{ //1.创建队列 //数据类型 变量名 dispatch_queue_t queue = dispatch_get_global_queue(0, 0); //2.创建任务 : void (^myTask)() = ^{ //代码块中是GCD要执行的任务 NSLog(@"%@",[NSThread currentThread]); }; //3.将任务添加到队列中 dispatch_async(queue, myTask);}
//简写demo1- (void)GCDDemo2{ dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"%@",[NSThread currentThread]); });}

pragma mark - GCD实现线程间的通信- (void)GCDDemo3{ dispatch_async(dispatch_get_global_queue(0, 0), ^{ NSLog(@"加载在下载... %@",[NSThread currentThread]); // 下载结束了,回到主线程刷新UI dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"刷新UI... %@",[NSThread currentThread]); }); });}

串行队列:里面的任务按照顺序依次调度执行,前面一个任务不执行完,后面的任务不会被调度. Serial 同时只能调度一个任务执行;队列的创建:dispatch_queue_t queue = dispatch_queue_create("TT", DISPATCH_QUEUE_SERIAL);

串行➕异步:会开一条心线程,因为是异步,而且mm不会最后打印,循环是有顺序的;- (void)GCDDemo1{ //创建队列 dispatch_queue_t queue = dispatch_queue_create("tt", DISPATCH_QUEUE_SERIAL); for (NSInteger i = 0; i < 10; i++) { //创建任务 void(^task)() = ^{ NSLog(@"%zd %@",i ,[NSThreadcurrentThread]); }; //添加到队列异步 dispatch_async(queue, task); } NSLog(@"mm");}

串行➕同步 :不会开新线程,会在当前的线程执行,mm会最后打印,循环是有顺序的- (void)GCDDemo1{ //创建队列 dispatch_queue_t queue = dispatch_queue_create("tt", DISPATCH_QUEUE_SERIAL); for (NSInteger i = 0; i < 10; i++) { //创建任务 void(^task)() = ^{ NSLog(@"%zd %@",i ,[NSThreadcurrentThread]); }; //添加到队列同步 dispatch_sync(queue, task); } NSLog(@"mm");}

并发队列:可以同时调度多个任务同时执行; Concurrent 自动开启多个线程同时执行多个任务
主队列:专门在主线程上调度任务,不会开启新线程,先进先出的方式,只有主线程空闲时才会调度队列中的任务在主任务执行,如果当前主线程有任务在执行,无论主队列被添加了什么任务,都不会被调度.dispatch_queue_t queue = dispatch_get_main_queue ();

全局队列:效果等同于并发队列;

任务:dispatch_sync (dispatch_queue_t queue ,dispatch_block_t block); 同步方式执行任务,只在当前的线程中依次执行任务;
dispatch_async (dispatch_queue_t queue ,dispatch_block_t block); 异步方式执行任务,新开线程,在新线程中执行任务;

dispatch_after (when ,queue ,block);真的一个异步函数;

同步任务由于是从上到下执行,可以知道具体哪个任务执行完了,但是异步任务顺序不一样,无法知道具体哪个任务完成了;调度组用来监听一组异步任务的状况;dispatch_group_async ();

单例特点:有一个方便外界调用的类方法,用来实例化单例对象;
保证这个类在程序运行的过程中,在内存中有且只有一个实例化对象
保存在内存的静态区(保证单例的生命周期和程序一样长)

缺点:单例保存在静态区,只有在APP死亡时才会结束;
static AudioTool *instance;+ (instancetype)sharedAudioTool{ static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [[AudioTool alloc] init]; }); return instance;}//由于viewController.m中alloc和shared调用的顺序不一样,所以后面的实现方法里面都重写一下dispatch_once,但是copy是对象copy,所以不用重写+ (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;}

  • 遍历

    • 下标遍历
    for i in 0..<array.count {
     print(array[i]) //输出:小明            
                     //     中花  
                     //     大杨
    }   
    
    • 直接内容遍历
    for s in array {
        print(s) //输出:小明
                 //     中花
                 //     大杨
     }
    
    • enum block遍历下标和内容
     for e in array.enumerated() {
        print("\(e.offset) \(e.element)") //输出:0 小明
                                          //     1 中花
                                          //     2 大杨
     }
    
    • 遍历下标和内容方式二
    for(n, s) in array.enumerated() {
            print("\(n) \(s)")  //输出:0 小明
                                //     1 中花
                             //     2 大杨
    }
    
    • 反序
     for s in array.reversed() {
            print(s) //输出:大杨
                     //     中花
                     //     小明
    }
    
    • 反序索引和内容
    //错的
    for (n, s) in array.reversed().enumerated() {
        print("\(n) \(s)")  //输出:0 大杨
                            //     1 中花
                            //     2 小明
    }
    //对的
    for (n, s) in array.enumerated().reversed() {
        print("\(n) \(s)") //输出:2 大杨
                           //    1 中花
                           //    0 小明
    }
    
- **增**

相关文章

  • 多线程之GCD

    GCD介绍 1、GCD简介 2、GCD任务和队列 3、GCD 的基本使用 4、GCD 线程间的通信 5、GCD 的...

  • 扩展GCD(求逆元,解同余方程等等)

    首先要知道gcd函数的基本性质:gcd(a,b)=gcd(b,a)=gcd(|a|,|b|)=gcd(b,a%b)...

  • iOS - GCD

    目录 GCD简介 GCD核心概念 GCD队列的使用 GCD的常见面试题 GCD简介 Grand Central D...

  • iOS-多线程:GCD

    GCD 简介 GCD 任务和队列 GCD 的使用步骤 GCD 的基本使用(6种不同组合区别) GCD 线程间的通信...

  • 浅析GCD

    GCD目录: 1. GCD简介 为什么要用GCD呢? GCD可用于多核的并行运算GCD会自动利用更多的CPU内核(...

  • 7.3 多线程-GCD

    多线程-GCD 多线程-GCD-串行并行 多线程-GCD.png GCD-线程的通讯、延时操作、定时器 GCD-线...

  • iOS 多线程--GCD

    一、GCD基本介绍 1.GCD简介 GCD是Grand Central Dispatch的缩写,GCD是苹果推出的...

  • 自用算法模板(JAVA版)

    一、数论 1)GCD GCD(求最大公约数) QGCD(快速GCD) extGCD(拓展GCD,解决ax + by...

  • GCD介绍

    一、GCD简单介绍 什么是GCD GCD优势 任务和队列 GCD有2个核心概念 GCD的使用就2个步骤 将任务添加...

  • 7.多线程基础(七)GCD加强

    1.GCD串行队列和并发队列 2.GCD延时执行 3.GCD线程组:(的作用) 4.GCD定时器: GCD的实现 ...

网友评论

      本文标题:GCD

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