zoukankan      html  css  js  c++  java
  • GCD总结

      //用block只有两种:同步执行/异步执行(参数1:队列;参数二:任务)

        dispatch_async(dispatch_get_global_queue(0, 0),^{

        });//异步在新的线程中执行任务,具备开启新线程能力,能跳过该代码执行后面代码

        dispatch_sync(dispatch_get_global_queue(0, 0), ^{

        });//同步:在当前线程中执行任务,不具备开启新线程能力,不能跳过该代码执行后面代码

        //队列:并发队列(可以让多个任务同时执行自动开启多个线程同时执行任务,注意:只有在异步时才有效)/串行队列(任务一个接一个按顺序依次执行,即一个任务执行完毕后,在执行下一个任务)

    //串行队列

        dispatch_queue_t queue1 = dispatch_queue_create("mm", DISPATCH_QUEUE_SERIAL);//串行队列

        dispatch_block_t task1 = ^{

            NSLog(@"%@",[NSThread currentThread]);

        };//创建任务

        dispatch_async(queue1, task1);//串行异步开启新线程,任务按顺序依次执行

        dispatch_sync(queue1, task1);//串行同步,不开启新线程,任务按顺序依次执行

    //并发队列

        dispatch_queue_t queue2 = dispatch_queue_create("mm", DISPATCH_QUEUE_CONCURRENT);//并发队列

        dispatch_block_t task2 = ^{

            NSLog(@"%@",[NSThread currentThread]);

        };//创建任务

        dispatch_async(queue2, task2);//并行异步开启多条线程,任务同时执行(不按顺序)

        dispatch_sync(queue2, task2);//并行同步,不开启新线程,任务在当前线程按顺序依次执行

    //全局队列(也叫做全局并发队列:)

        dispatch_queue_t globalQueue =  dispatch_get_global_queue(0, 0);//全局队列(参数1:服务质量,类似于优先级;参数2:预留参数)

        dispatch_block_t globaltask = ^{

            NSLog(@"%@",[NSThread currentThread]);

        };//创建任务

        dispatch_async(globalQueue,globaltask);//全局异步任务;并行异步开启多条线程,任务同时执行(不按顺序)

        dispatch_sync(globalQueue,globaltask);//全局同步任务;并行同步,不开启新线程,任务在当前线程按顺序依次执行

        //注意:全局变量就是并发队列;区别:全局队列没有名称,无法跟踪错误,而并发队列可以实现;而且arc中不需要考虑释放内存,dispatch_release不允许调用,在mrc中需要手动释放内存,并发队列是creat出来的,在mrc中见到creat就要release,全局队列不需要release(只有一个,类似单例);一般我们使用全局队列;

        

    //主队列(也叫全局串行队列:不创建新线程,主队列里的任务一定在主线程完成,而且必须在主线程空闲时才能执行主队列里的任务)

        dispatch_queue_t mainQueue =  dispatch_get_main_queue();//主队列(就是串行队列)

        

        dispatch_block_t maintask = ^{

            NSLog(@"%@",[NSThread currentThread]);

        };//创建任务

        dispatch_async(mainQueue,maintask);//主队列异步:在主线程执行,任务依次按顺序执行

        dispatch_sync(mainQueue,maintask);//主队列同步:(死锁:原因是互相等待造成死锁)在主线程执行

        //死锁原因:由于主线程执行代码是按从上到现依次执行方式,所以当代码按顺序执行到主队列时,主线程停下来等待主队列执行队列里的代码;而主队列执行代码条件是只有当主线程空闲时才能执行,所以主队列等待主线程执行完毕空闲下来;这样就导致主队列与主线程相互等待.程序无法继续进行,造成死锁.

        //死锁解决方法:就是将主队列同步任务放在一个全局异步队列中去.这样使得主线程得以执行完毕空闲下来,这样就满足了主队列执行条件,主队列中的代码得以执行,死锁就解开了.(实质就是将主队列任务放到一个异步操作中去,让主队列任务在新线程中去执行)

        

    //GCD使用

      //1.同步任务(按顺序执行/彼此依赖)例如:appStore 验证用户密码-扣费-下载应用

        //特点:在队列调度做个异步任务前,指定一个同步任务,让所有异步任务都等待同步任务完成,这就是所谓"依赖"关系;

        //需求:1.操作耗时,需到子线程执行;2.有依赖关系

        dispatch_sync(dispatch_get_global_queue(0, 0), ^{

            dispatch_async(dispatch_get_global_queue(0, 0), ^{

                [NSThread sleepForTimeInterval:2];

                NSLog(@"验证密码");

            });

            dispatch_async(dispatch_get_global_queue(0, 0), ^{

                [NSThread sleepForTimeInterval:2];

                NSLog(@"扣费");

            });

            dispatch_async(dispatch_get_global_queue(0, 0), ^{

                [NSThread sleepForTimeInterval:2];

                NSLog(@"下载应用");

            });

        });

      

    //线程间通信

        dispatch_async(dispatch_get_global_queue(0, 0), ^{

            NSURL *url = [NSURL URLWithString:@""];

            NSData *data = [NSData dataWithContentsOfURL:url];

            UIImage *image = [UIImage imageWithData:data];

            //刷新UI 回到主线程就是使用主队列

            dispatch_async(dispatch_get_main_queue(), ^{

                UIImageView *imgView = [[UIImageView alloc]initWithImage:image];

            });

        });

        

    //延时操作(是通过dispatch_after(<#dispatch_time_t when#>, <#dispatch_queue_t queue#>, <#^(void)block#>)实现的,只不过默认使用了主队列.(参数1.等待时间;参数2.执行队列;参数3.执行任务))

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            NSLog(@"等了好久");

        });

    //调度组

        dispatch_group_t group = dispatch_group_create();//创建调度组

        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{

            [NSThread sleepForTimeInterval:2];

            NSLog(@"第一首下载成功");

        });

        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{

            [NSThread sleepForTimeInterval:2];

            NSLog(@"第二首下载成功");

        });

        dispatch_group_async(group, dispatch_get_global_queue(0, 0), ^{

            [NSThread sleepForTimeInterval:2];

            NSLog(@"第三首下载成功");

        });

        //回主队列提醒用户

        dispatch_group_notify(group, dispatch_get_main_queue(), ^{

            NSLog(@"歌曲下载完成");

        });

        //调度组实现原理

         dispatch_group_t group1 = dispatch_group_create();//创建调度组

        dispatch_group_enter(group1);

        dispatch_async( dispatch_get_global_queue(0, 0), ^{

            [NSThread sleepForTimeInterval:2];

            NSLog(@"第一首下载成功");

            dispatch_group_leave(group1);

        });

        dispatch_group_enter(group1);

        dispatch_async(dispatch_get_global_queue(0, 0), ^{

            [NSThread sleepForTimeInterval:2];

            NSLog(@"第二首下载成功");

             dispatch_group_leave(group1);

        });

        dispatch_group_enter(group1);

        dispatch_async(dispatch_get_global_queue(0, 0), ^{

            [NSThread sleepForTimeInterval:2];

            NSLog(@"第三首下载成功");

             dispatch_group_leave(group1);

        });

        //回主队列提醒用户

        dispatch_group_notify(group, dispatch_get_main_queue(), ^{

            NSLog(@"歌曲下载完成");

        });

        

    //一次性执行(用来实现单例)应用场景:音乐播放器,视频播放器,封装网络下载工具类

        [UIApplication sharedApplication];

        [NSUserDefaults standardUserDefaults];

        [NSNotificationCenter defaultCenter];

        [NSFileManager defaultManager];

        //单例(一种设计模式,特点:只要一创建就一直存在于app中,知道应用程序退出才销毁, static静态区:(一旦创建直到程序退出才销毁));单例不能滥用,原因是其特点决定,一旦创建知道程序退出销毁才释放,占大量内存资源,移动端内存本来就小,因此不能滥用;

        static dispatch_once_t onceToken;

        dispatch_once(&onceToken, ^{

            NSLog(@"一次性执行");

        });

        //创建单例一般用shared+类名;

        /*

         1.以前未使用互斥锁,存在线程安全问题,添加互斥锁才安全,但此方法效率没有用一次性执行高

         .h中:

         +(instancetype)sharad+类名;

         .m中:

         static id _instanceType;

         +(instancetype)sharad+类名

         {

          @synchronized(self) {

         if (_instanceType == nil) {

         _instanceType = [[self alloc]init];

           }

          }

         return _instanceType;

         }

         2.一次性执行

         在ARC下:

         .h中:

         +(instancetype)sharad+类名;

         .m中:

         static id _instanceType;

         +(instancetype)sharad+类名

         {

         //一次性执行实现单例

         static dispatch_once_t onceToken;

         dispatch_once(&onceToken, ^{

         _instanceType = [[self alloc]init];

         });

         return _instanceType;

         }

         调用alloc最终会调用此方法

         + (instancetype)allocWithZone:(struct _NSZone *)zone

         {

         static dispatch_once_t onceToken;

         dispatch_once(&onceToken, ^{

         _instanceType = [super allocWithZone:zone];

         });

         return _instanceType;

         }

         调用alloc最终会调用此方法(ios7之前要遵循NSCopying协议)

         -(id)copyWithZone:(NSZone *)zone

         {

         return _instanceType;

         }

         在MRC中.m里需添加以下方法:

         -(oneway void)release

         {

         

         }

         -(instancetype)retain

         {

         return _instanceType;

         }

         -(instancetype)autorelease

         {

         return _instanceType;

         }

         - (NSUInteger)retainCount

         {

         return 1;

         }

        */

        

        /*提取单例宏,创建 singleton.h文件 

         导入头文件

         使用.h中  singleton_h(类名)

         使用.m中  singleton_m(类名)

         

         #if __has_feature(objc_arc) //ARC

         //.h 拼接参数使用##

         #define singleton_h(name) +(instancetype)sharad##name;

         

         //.m 宏里面换行

         #define singleton_m(name) static id _instanceType;

         +(instancetype)sharad##name

         {

         static dispatch_once_t onceToken;

         dispatch_once(&onceToken, ^{

         _instanceType = [[self alloc]init];

         });

         return _instanceType;

         }

         + (instancetype)allocWithZone:(struct _NSZone *)zone

         {

         static dispatch_once_t onceToken;

         dispatch_once(&onceToken, ^{

         _instanceType = [super allocWithZone:zone];

         });

         return _instanceType;

         }

         -(id)copyWithZone:(NSZone *)zone

         {

         return _instanceType;

         }

         

         

         #else //MRC

         //.h 拼接参数使用##

         #define singleton_h(name) +(instancetype)sharad##name;

         

         //.m 宏里面换行

         #define singleton_m(name) static id _instanceType;

         +(instancetype)sharad##name

         {

         static dispatch_once_t onceToken;

         dispatch_once(&onceToken, ^{

         _instanceType = [[self alloc]init];

         });

         return _instanceType;

         }

         + (instancetype)allocWithZone:(struct _NSZone *)zone

         {

         static dispatch_once_t onceToken;

         dispatch_once(&onceToken, ^{

         _instanceType = [super allocWithZone:zone];

         });

         return _instanceType;

         }

         -(id)copyWithZone:(NSZone *)zone

         {

         return _instanceType;

         }

         -(oneway void)release

         {

        

         }

         -(instancetype)retain

         {

         return _instanceType;

         }

         -(instancetype)autorelease

         {

         return _instanceType;

         }

         - (NSUInteger)retainCount

         {

         return 1;

         }

         

         #endif

        */

        

        

  • 相关阅读:
    日本美女自拍大赛作品欣赏 最后一张看醉了
    BERT(Bidirectional Encoder Representations from Transformers)理解
    P-R曲线及与ROC曲线区别
    残差网络(Residual Network)
    Attention is all you need 论文详解(转)
    联合建模心得
    拒绝推断问题(转)
    关联规则简述
    pycharts实现可视化
    CRF++进行中文分词实例
  • 原文地址:https://www.cnblogs.com/niumingming920322/p/5862408.html
Copyright © 2011-2022 走看看