并发队列,iOS开发之GCD并发队列

iOS开垦八线程之GCDiOS开荒之GCD同步职务压实iOS开拓之GCD串行队列iOS开荒之GCD并发队列

MARK:并发队列,异步执行-gcdDemo3{ //1.队列-并发 DISPATCH_QUEUE_CONCURRENT 并发 dispatch_queue_t q = dispatch_queue_create("cc_queue",DISPATCH_QUEUE_CONCURRENT); //2.异步执行任务 for(int i = 0;i < 10;i  ) { dispatch_async(q,^{ NSLog(@"%@ %d",[NSThread currentThread],i); }); } NSLog(@"come here");}

GCD,全称是 Grand Central Dispatch,纯 C 语言,提供了比很多强盛的函数. 是苹果公司为多核的交互运算建议的缓和方案, 会自动利用更多的CPU内核(比方双核、四核), 会自动管理线程的生命周期(创制线程、调节职责、销毁线程), 技术员只要求报告 GCD 想要实施什么样义务,不需求编写制定任何线程管理代码.

03 GCD-并发队列

并发队列,异步试行

MARK:并发队列,异步执行-gcdDemo3{ //1.队列-并发 DISPATCH_QUEUE_CONCURRENT 并发 dispatch_queue_t q = dispatch_queue_create("cc_queue",DISPATCH_QUEUE_CONCURRENT); //2.异步执行任务 for(int i = 0;i < 10;i  ) { dispatch_async(q,^{ NSLog(@"%@ %d",[NSThread currentThread],i); }); } NSLog(@"come here");}

标题:1.会开几条线程?会开多条线程,线程数量是由GCD来决定2.会依次执可以吗?不会3.come here的位置?不鲜明,日常会靠上的岗位

看起来职分推行的是逐条的。是因为线程的耗费时间基本上。最重大原由是,线程取职务是各种取的。

并发队列,同步执行

MARK:并发队列,同步执行-gcdDemo4{ //1.队列-并发 DISPATCH_QUEUE_CONCURRENT 并发 dispatch_queue_t q = dispatch_queue_create("cc_queue",DISPATCH_QUEUE_CONCURRENT); //2.同步执行任务 for(int i = 0;i < 10;i  ) { dispatch_sync(q,^{ NSLog(@"%@ %d",[NSThread currentThread],i); }); } NSLog(@"come here");}

主题素材:1.会开几条线程?不会2.会种种执可以吗?顺序3.come here的位置?最后

标题:1.会开几条线程?会开多条线程,线程数量是由GCD来决定2.会一一实践呢?不会3.come here的位置?不鲜明,平日会靠上的职位

骨干概念

比较串行队列同步职务 和 并发队列同步职分

  • 2者之间的结果是一模二样的。只要一起实行,不管是串行依旧并行都以 同样的。

三只实施:不会到线程池里面去获取子线程异步试行:只要有职责,就能到线程池取子线程

mainQueue是各类推行

看起来职责试行的是逐条的。是因为线程的耗费时间大约。最重大原由是,线程取职分是逐个取的。

  1. 将职责增加到行列,何况内定实践职分的函数

  2. 职务使用block封装

小结

开不开线程,取决去职分的函数,同步不开,异步技能开;开几条线程,决定于队列,串行开一条,并发能够开多条

MARK:并发队列,同步执行-gcdDemo4{ //1.队列-并发 DISPATCH_QUEUE_CONCURRENT 并发 dispatch_queue_t q = dispatch_queue_create("cc_queue",DISPATCH_QUEUE_CONCURRENT); //2.同步执行任务 for(int i = 0;i < 10;i  ) { dispatch_sync(q,^{ NSLog(@"%@ %d",[NSThread currentThread],i); }); } NSLog(@"come here");}

        职分的block未有参数也从不再次来到值

引入文集

初稿小编:集才华美丽于一身的—C姐

主题材料:1.会开几条线程?不会2.会梯次实践呢?顺序3.come here的位置?最后

  1. 推行职分的函数

比较串行队列同步任务 和 并发队列同步职务

  • 2者之间的结果是平等的。只要一同实行,不管是串行仍然并行都是 一样的。

一块施行:不会到线程池里面去获取子线程异步试行:只要有任务,就能够到线程池取子线程

mainQueue是逐条推行

       异步dispatch_async

小结

  • 开不开线程,取决去职务的函数,同步不开,异步技艺开;
  • 开几条线程,决议于队列,串行开一条,并发能够开多条

           不用等待日前语句实行完成,就能够施行下一条语句

           会开启线程执行block的职分

           异步是二十多线程的代名词

       同步dispatch_sync

             必需等待日前语句实行实现,才会进行下一条语句

             不会敞开线程

            在时下实践block的任务

  1. 队列- 系统以先进先出的措施调节队列中的职分实践

        串行队列

              二遍只好"调节"一个职责 

             dispatch_queue_create("cn.itcast.queue", NULL);

       并发队列

              二次能够"调节"四个任务

             dispatch_queue_create("cn.itcast.queue", DISPATCH_QUEUE_CONCURRENT);

       主队列

            特地用来在主线程上调节职责的队列

            不会展开线程

              在主线程空闲时才会调整队列中的任务在主线程推行

              dispatch_get_main_queue();

      全局队列

            为了方便技士的应用,苹果提供了全局队列

dispatch_get_global_queue(0, 0)

            全局队列是一个并发队列

            在应用十六线程开辟时,假诺对队列未有异样必要,在实施异步义务时,可以一向使           用全局队列

小结:

开不开线程由施行职务的函数决定

         异步开,异步是八线程的代名词

         同步不开

开几条线程由队列决定

        串行队列开一条线程

        并发队列开多条线程,具体能开的线程数量由底层线程池决定

                iOS 8.0 之后,GCD 可以开启极其多的线程

                iOS 7.0 以至此前,GCD 平常只会开启 5~6 条线程

- 队列的拈轻怕重

二十四线程的目标:将耗费时间的操作放在后台推行!

串行队列,只开一条线程,全数义务逐条实施

         假设职责有程序实践各类的渴求

         效率低 -> 执行慢 -> "省电"

        临时,客商实际不期待太快!举例利用 3G 流量,"积攒零钱"

并发队列,会敞开多条线程,全体职分不遵照顺序实施

       借使职责未有前后相继进行顺序的渴求

       效率高 -> 执行快 -> "费电"

       WIFI,包月

实质上支出中,线程数量如何决定?

       WIFI 线程数6条

       3G / 4G 移动支付的时候,2~3条,再多会费电费钱!

全局队列 和 主队列

全局队列

为了方便程序猿的应用,苹果提供了大局队列dispatch_get_global_queue(0, 0)

大局队列是三个并发队列,立刻会讲

在应用四线程开荒时,假设对队列未有异样供给,在施行异步职责时,能够一向利用全局队列

主队列

为了方便线程间通讯,异步试行完网络职责,在主线程更新 UI

苹果提供了主队列dispatch_get_main_queue()

主队列专门用于在主线程上调治职分试行

异步实施职分

- (void)gcdDemo1 {

// 1. 大局队列

dispatch_queue_tqueue = dispatch_get_global_queue(0,0);

// 2. 任务

dispatch_block_t task = ^ {

NSLog(@"hello gcd %@", [NSThreadcurrentThread]);

    };

// 3. 将任务加多到行列,何况钦定异步施行

dispatch_async(queue, task);

}

专一:如若等待时间长一些,会发觉线程的number爆发变化,由此能够测算gcd 底层线程池的劳作

简短代码

仿照循环加多 10 个异步下载图像的人物

// 精简代码

- (void)gcdDemo2 {

for(NSInteger i =0; i <10; i ) {

        [NSThread sleepForTimeInterval:0.5];

dispatch_async(dispatch_get_global_queue(0,0), ^{

NSLog(@"下载图像 %zd %@", i, [NSThreadcurrentThread]);

        });

    }

}

NSThread 实现等价代码相比

#pragma mark - NSThread 代码

- (void)threadDemo {

for(NSInteger i =0; i <10; i ) {

        [NSThread sleepForTimeInterval:0.5];

        [NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:@(i)];

    }

}

- (void)downloadImage:(id)obj {

NSLog(@"下载图像 %@ %@", obj, [NSThreadcurrentThread]);

}

与NSThread的对比

1.全数的代码写在协同的,让代码越发简明,易于阅读和保证

         NSThread通过@selector内定要实施的办法,代码分散

         GCD通过block钦定要实行的代码,代码集中

2.应用GCD不要求管理线程的创始/销毁/复用的历程!程序猿不用关怀线程的生命周期

3.假诺要开多个线程NSThread必得实例化多少个线程对象

4.NSThread靠NSObject的归类方法完结的线程间通信,GCD靠block

线程间通讯

#pragma mark - 线程间通信

- (void)gcdDemo3 {

dispatch_async(dispatch_get_global_queue(0,0), ^{

// 异步下载图像

NSLog(@"下载图像 %@", [NSThread currentThread]);

// 主线程更新

UIdispatch_async(dispatch_get_main_queue(), ^{

NSLog(@"主线程更新 UI %@", [NSThread currentThread]);

        });

    });

}

上述代码是GCD最常用代码组合!

互连网下载图片

- (void)viewDidLoad {

    [super viewDidLoad];

// 1. 准备

URLNSString*urlString =@"";

NSURL*url = [NSURLURLWithString:urlString];

// 2. 下载图像

dispatch_async(dispatch_get_global_queue(0,0), ^{

// 1> 全体从互连网重回的都以二进制数据

NSData*data = [NSData dataWithContentsOfURL:url];

// 2> 将二进制数据转换来 image

UIImage*image = [UIImage imageWithData:data];

// 3> 主线程更新UI

dispatch_async(dispatch_get_main_queue(), ^{

// 1> 设置图像

_imageView.image= image;

// 2> 调度大小

[_imageView sizeToFit];

// 3> 设置 contentSize

_scrollView.contentSize= image.size;

        });

    });

}

串行队列

特点

以先进先出的章程,顺序调节队列中的任务实践

不管队列中所钦命的执行职务函数是联合依旧异步,都会等待前八个任务推行到位后,再调整后边的天职

队列创造

dispatch_queue_t queue = dispatch_queue_create("com.itheima.queue", DISPATCH_QUEUE_SERIAL);

dispatch_queue_t queue = dispatch_queue_create("com.itheima.queue",NULL);

串行队列 同步实行

/// 串行队列 - 同步进行

/// 提问:是或不是开线程?是不是顺序推行?come here 的职位?

/// 回答:不会开线程/顺序实行/最终

- (void)gcdDemo1 {

// 1. 串行队列

dispatch_queue_t queue = dispatch_queue_create("cn.itcast.queue", DISPATCH_QUEUE_SERIAL);

// 2. 拉长同步实践的义务

for(NSInteger i =0; i <10; i ) {

dispatch_sync(queue, ^{

            [NSThread sleepForTimeInterval:0.5];

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

        });

    }

NSLog(@"come here");

}

串行队列 异步实践

/// 串行队列 - 异步推行

/// 提问:是或不是开线程?是或不是顺序实施?come here 的岗位?

/// 回答:会开一条线程/顺序执行/不明确

- (void)gcdDemo2 {

// 1. 串行队列

dispatch_queue_t queue = dispatch_queue_create("cn.itcast.queue", DISPATCH_QUEUE_SERIAL);

// 2. 增多异步试行的天职

for(NSInteger i =0; i <10; i ) {

dispatch_async(queue, ^{

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

        });

    }

NSLog(@"come here");

}

并发队列

特点

以先进先出的办法,并发调整队列中的职分实行

假定当前调治的任务是手拉手实践的,会等待义务奉行到位后,再调解后续的职责

举例当前调治的天职是异步实行的,况且底层线程池有可用的线程财富,会再新的线程调整后续职责的实践

队列创立

dispatch_queue_t queue = dispatch_queue_create("com.itheima.queue", DISPATCH_QUEUE_CONCURRENT);

并发队列 异步施行

/// 并发队列 - 异步实行

/// 提问:是或不是开线程?是或不是顺序推行?come here 的职责?

/// 回答:会开线程(决议于底层线程池可用财富)/不是各样奉行/不分明

- (void)gcdDemo2 {

// 1. 并发队列

dispatch_queue_t queue = dispatch_queue_create("cn.itcast.queue", DISPATCH_QUEUE_CONCURRENT);

// 2. 抬高异步实践的任务

for(NSInteger i =0; i <10; i ) {

dispatch_async(queue, ^{

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

        });

    }

NSLog(@"come here");

}

并发队列 同步施行

/// 并发队列 - 同步进行

/// 提问:是或不是开线程?是还是不是顺序推行?come here 的义务?

/// 回答:不开线程/顺序实施/最后

- (void)gcdDemo1 {

// 1. 并发队列

dispatch_queue_t queue = dispatch_queue_create("cn.itcast.queue", DISPATCH_QUEUE_CONCURRENT);

// 2. 加上同步试行的天职

for(NSInteger i =0; i <10; i ) {

dispatch_sync(queue, ^{

            [NSThread sleepForTimeInterval:0.5];

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

      });

    }

NSLog(@"come here");

}

主队列

特点

专程用来在主线程上调治任务的队列

不会敞开线程

以先进先出的不二诀要,在主线程空闲时才会调治队列中的任务在主线程实践

倘使当前主线程正在有义务执行,那么不论主队列中当前被加多了哪些职务,都不会被调整

队列获取

主队列是负担在主线程调节职责的

会趁机程序运营一同创办

主队列只须求猎取不用创制

dispatch_queue_t queue = dispatch_get_main_queue();

主队列,异步施行

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event {

    [self gcdDemo1];

    [NSThread sleepForTimeInterval:1.0];

NSLog(@"over");}

/// 主队列异步

/// 提问:是或不是开线程?是不是顺序实行?come here 的岗位?

/// 回答:不开/顺序/最前面

- (void)gcdDemo1 {

// 1. 主队列

dispatch_queue_t queue = dispatch_get_main_queue();

// 2. 异步职务

for(NSInteger i =0; i <10; i ) {

dispatch_async(queue, ^{

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

        });

    }

NSLog(@"come here");

}

在主线程空闲时才会调节主队列中的职责在主线程试行

主队列,同步实行

/// 主队列同步

- (void)gcdDemo2 {

NSLog(@"begin");

// 1. 主队列

dispatch_sync(dispatch_get_main_queue(), ^{

NSLog(@"hello"); 

  });

NSLog(@"end");

}

主队列和主线程相互等待会促成死锁

大局队列

是系统为了便于程序员开采提供的,其行事表现与并发队列一致

大局队列 & 并发队列的分别

大局队列

从没称谓

无论 MRC & ARC 都不必要思考释放

平常开销中,建议采纳"全局队列"

并发队列

盛名字,和NSThread的name属性功能类似

要是在 MRC 开辟时,需求选拔dispatch_release(q);释放相应的靶子

dispatch_barrier必需利用自定义的产出队列

支付第三方框架时,建议利用并发队列

大局队列 异步职务

/**

叩问:是不是开线程?是不是顺序实践?come here 的岗位?

*/

- (void)gcdDemo8 {

// 1. 队列

dispatch_queue_t q = dispatch_get_global_queue(0,0);

// 2. 奉行职务

for(int i =0; i <10; i) {

dispatch_async(q, ^{

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

        });

    }

NSLog(@"come here");

}

运转效果与并发队列相同

参数

服务品质(队列对任务调解的优先级)/iOS 7.0 在此之前,是先行级

iOS 8.0(新扩张,暂且不可能用,二〇一四年年末)

QOS_CLASS_USER_INTERACTIVE0x21, 顾客交互(希望最快完毕-不能够用太耗费时间的操作)

QOS_CLASS_USER_INITIATED0x19, 客户期待(希望快,也无法太耗时)

QOS_CLASS_DEFAULT0x15, 暗许(用来底层复位队列使用的,不是给技师用的)

QOS_CLASS_UTILITY0x11, 实用工具(特意用来管理耗费时间操作!)

QOS_CLASS_BACKGROUND0x09, 后台

QOS_CLASS_UNSPECIFIED0x00, 未指定,可以和iOS 7.0 适配

iOS 7.0

DISPATCH_QUEUE_PRIORITY_HIGH2 高优先级

DISPATCH_QUEUE_PRIORITY_DEFAULT0 暗中同意优先级

DISPATCH_QUEUE_PRIORITY_LOW(-2) 低优先级

DISPATCH_QUEUE_PRIORITY_BACKGROUNDINT16_MIN 后台优先级

为今后保留使用的,应该恒久传入0

结论:假设要适配 iOS 7.0 & 8.0,使用以下代码:dispatch_get_global_queue(0, 0);

单例

一些时候,在程序支付中,有个别代码只想从程序运营就只进行三次,标准的施用场景就是“单例”

单例的特征

在内部存储器中独有二个实例

提供八个大局的访问点

唤醒:单例的使用在 iOS 中国和北美洲常普及,以下代码在无数供销社的面试中,都要求能够手写出来

- (void)once {

static dispatch_once_t onceToken;

NSLog(@"%zd", onceToken);

// onceToken == 0 的时候实行 block 中的代码

// block 中的代码是共同试行的

dispatch_once(&onceToken, ^{

NSLog(@"执行了");

    });

NSLog(@"come here");

}

dispatch 内部也可以有一把锁,是能力所能达到确认保证"线程安全"的!而且是苹果集团推举使用的

以下代码用于测量检验八线程的贰回性执行

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent*)event {

for(NSInteger i =0; i <10; i ) {

dispatch_async(dispatch_get_global_queue(0,0), ^{

            [self once];

        }); 

  }

}

单例的特色

在内部存款和储蓄器中唯有一个实例

提供二个大局的访谈点

懒汉式单例达成

所谓懒汉式单例,表示在应用时才会创建

@implementation NetworkTools

(instancetype)sharedTools {

static id instance;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

        instance = [[self alloc] init];

    });

return instance;

}

@end

面试时只要落成地点sharedTools方法就能够

饿汉式单例达成

所谓饿汉式单例,表示尽快地开创单例实例,能够应用initialize方法成立单例

static id instance;

/// initialize 会在类第二遍被运用时调用

/// initialize 方法的调用是线程安全的

(void)initialize {

NSLog(@"创立单例");

    instance = [[self alloc] init];

}

(instancetype)sharedTools {

return instance;

}

本文由星彩网app下载发布于计算机编程,转载请注明出处:并发队列,iOS开发之GCD并发队列

TAG标签: 星彩网app下载
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。