【澳门葡京备用网址】牛逼的心脏调治器,二十八线程之GCD详解

  • GCD是苹果公司为多核的并行运算提出的缓慢解决方案
  • GCD会自行利用越来越多的CPU内核
  • GCD会自行处理线程的生命周期(成立线程、调整职分、销毁线程)
  • GCD是纯C语言完结的,提供了充足多强大的函数

互联网上有比非常多关于GCD的篇章,所以请不要相比较,那个只是自家纪录学习进程而已

同步、异步、并发、串行


/*

一道:在脚下线程中实施

异步:在另一条线程中操作,开启了新线程

并发:让多个线程职分同时执行

串行:让职务三个接二个的实行

*/

/**

GCD:Grand Center Dispatch –宏大的大旨调节(牛逼的命脉调节器)

纯C语言,提供了极度多庞大的函数

1苹果公司为多核的并行运算提议的消除方案

2方可选拔越来越多的拍卖中央

3不用关爱线程代码,gcd会创立线程代码,调解职务

优势:自动管理线程的生命周期(创制线程、调解职责、销毁线程)

技师只须要报告GCD大家想要实行怎么样任务,无需编写制定任何线程管理代码

GCD中有2个为主概念

(1)职务:实施如何操作—block

(2)队列:用来寄放职责—queue

GCD中有多少个宗旨概念:

1.简介

  • 什么是GCD

    • 万事俱备是Grand Central Dispatch,可译为“二十四线程优化技艺”
    • 纯C语言编写,提供了极度庞大的函数
  • 【澳门葡京备用网址】牛逼的心脏调治器,二十八线程之GCD详解。GCD的优势

  • GCD是苹果公司为多核的互相运算建议的实施方案

  • GCD会自动利用越来越多的CPU内核(比如双核、四核)

  • GCD会自动管理线程的生命周期(创造线程、调节职分、销毁线程)

  • 技士只要求报告GCD想要试行什么样职责,无需编写制定任何线程管理代码

  • GCD属于系统级的线程管理,在Dispatch
    queue中推行供给执行的天职性能非常的高。(PS:
    GCD那块已经开源,地址:https://apple.github.io/swift-corelibs-libdispatch/)

  • GCD中的FIFO队列称为dispatch_queue,用来确认保障先进来的天职先拿走实施。

共同:在时下线程中进行

  • 基本概念
  • 职分与队列
  • 队列的创始
  • 线程间的通讯
  • 别的用法
  • 职责:实行什么样操作
  • 队列:用来寄存在职务

2.职务和队列

  • GCD中有2个主导概念(轻松的话)
    • 职务:实施怎么着操作
    • 队列:用来寄放职分

异步:在另一条线程中实行

GCD的队列分为2大门类:

  • 什么是GCD?

    • 万事俱备是 Grand Central Dispatch(翻译一下是巨大的灵魂调解器)
    • 纯 C语言,提供了老大有力的函数
  • GCD的优势

    • GCD是苹果公司为多核的并行运算提出的缓和方案
    • GCD会活动利用更加多的CPU内核
    • GCD会活动地保管线程的生命周期(创立线程、调整线程、销毁线程)
    • 技士只要求报告GCD想要实践如何任务,无需编写制定任何线程管理代码
  1. 钦定职责,显著想做的事体
  2. 将职分增加到行列中,GCD会活动将队列中的职务抽取来放到对应的线程中实践。队列的抽取遵循队列的FIFO原则:先进先出,后进后出

复杂点说正是:

  • 任务:正是实践操作的意味,换句话说正是您在线程中试行的这段代码。在GCD中是放在block中的。实施任务有三种办法:同步实施和异步试行。两个的首要不同是:是还是不是具备开启新线程的力量。

    • 一块实行(sync):只能在当下线程中实行职责,不辜负有开启新线程的技术
    • 异步施行(async):能够在新的线程中实行职分,具备开启新线程的力量
  • 队列:这里的行列指职务队列,即用来寄存在任务的队列。队列是一种至极的线性表,选取FIFO(先进先出)的法则,即新任务三翻五次被插入到行列的结尾,而读取职责的时候总是从队列的尾部开头读取。每读取二个义务,则从队列中释放二个职务。在GCD中有三种队列:串行队列和产出队列。

    • 并发队列(Concurrent Dispatch
      Queue):能够让多个职务并发(同一时间)试行(自动开启八个线程同一时候推行职责)
    • 并发功用唯有在异步(dispatch_async)函数下才有效
  • 串行队列(Serial Dispatch
    Queue):让职责叁个随着一个地实行(二个任务试行完成后,再实践下三个职责)

  • GCD的应用就2个步骤

    • 创建队列(串行队列或并发队列),也能够说是定制职务

      • 规定想做的作业
    • 将职务增添到行列中

    • GCD会活动将队列中的职分抽取,放到对应的线程中施行

    • 任务的收取服从队列的FIFO原则:先进先出,后进后出

并发队列:可以让四个职分并发(同期)实践–并发功效只有在异步函数下才使得

GCD中有五个能够用来进行职责的函数

3.试行职责

  • GCD中有2个用来举办职责的常用函数

  • 用联合的不二诀窍执行职分
    dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

    • queue:队列
    • block :任务
  • 用异步的法子推行职责
    dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

  • 二只和异步的界别

  • 一块:只可以在时下线程中实践职务,不有所开启新线程的力量

  • 异步:能够在新线程中施行职责,具有开启新线程的技术

串行队列:职责贰个接三个地举办(壹个任务实践完结再试行下八个职务)

有多少个属于相比较轻巧模糊:同步、异步、并发、串行

1.联合签名和异步决定了要不要敞开新的线程:

联机:在最近线程中实施职分,不具备开启线程的力量

异步:在新的线程中推行任务,具有开启新线程的力量

2.并发和串行决定了职分的执行办法:

出现:多个职分并发(同期)推行

串行:一个职责实施完结后,再试行下二个职务

GCD中有三个施行职务的函数:

1.用一块格局实践任务:dispatch_sync

2.用异步情势实践任务:dispatch_async

GCD中获取串行队列有三种门路:

1.使用dispatch_queue_create函数创制串行队列//几个参数:1.队列名称2.队列属性,一般用NULL就能够

2.dispatch_get_main_queue
–使用主队列(和主线程相关的队列)–主队列是GCD自带的一种特别的串行队列,放在主队列中的职分,都会安放主线程中施行

使用dispatch_get_main_queue()得到主队列

GCD中收获并发队列有二种渠道:

GCD暗中认可已经提供了大局的面世队列,供整个应用使用,没有供给手动创制

使用dispatch_get_global_queue函数拿到全局的出现队列

各样队列实行功效

全局并发队列手动创设,串行队列主队列

贰只(sync)未有展开新线程

串行施行任务

异步(async)有张开新线程

并发施行职务

GCD的运用就2个步骤

(1)定制任务

(2)鲜明想做的事情

将任务增多到行列中,GCD会活动将队列中的任务收取,放到对应的线程中实践

提示:职责的抽取遵从队列的FIFO原则:先进先出,后进后出

*/

  • GCD中有八个大旨职分

    • 职务:实践怎么着操作
    • 队列:用来寄放职责
  • GCD的利用就2个步骤

    • 定制任务:明确想做的业务
    • 将职分增加到行列中:GCD会自行将队列中的职务抽取,放到对应的线程中实践
    • 使命的抽取遵守队列FIFO原则:先进先出,后进后出
  • 实行任务的不二秘诀

    • 用协同的方法施行任务dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);queue:队列block:任务
  • 用异步的办法奉行职务dispatch_async(dispatch_queue_t queue,dispatch_block_t block);

  • 一块和异步的分歧

  • 手拉手:同步只可以在如今的线程中进行职责,不具备开启新线程的力量

  • 异步:可以在新的线程中实行任务,具有开启新线程的力量

  • 队列的种类

    • 并发队列(Concurrent Dispatch Queue)
      • 能够让多少个任务并发实践,自动开启多个线程同一时候进行任务
      • 并发效用只有在异步函数(dispatch_async)下才有效
  • 串行队列(塞里al Dispatch Queue)

    • 让任务三个随着一个地施行(也正是说须等一个任务实施达成后才方可试行下多少个职分)
  • 轻易混淆的术语在付出中,大家很轻易搞混有同步、异步,并发、串行的含义,上边呢笔者再注重重申一下中间的差别

    • 协助举行和异步主要影响:能否张开新的线程
    • 一同:只是在脚下线程中执行职分,不持有开启新线程的力量
    • 异步:能够在新的线程执行职分,具有开启新线程的力量
    • 并发和串行主要影响:任务的实践形式
    • 并发:(必需接纳异步本事促成产出)允许几个职分并发推行
  • 串行:多少个职分完成后,再实行下三个职务

  • 用联合的章程试行任务:只好在现阶段线程中实施,不会开其余线程

4.队列详解

听大人讲影响点分别

4.1.并发队列

  • 使用dispatch_queue_create 函数创立队列

dispatch_queue_t
// const char *label  队列名称
//  dispatch_queue_attr_t attire 队列的类型
/*
 其中队列的类型有: 
 DISPATCH_QUEUE_CONCURRENT:并发
 DISPATCH_QUEUE_SERIAL:串行
*/
dispatch_queue_create(const char *label,dispatch_queue_attr_t attr);
  • 开创并发队列

dispatch_queue_t queue = dispatch_queue_create("com.WenJim.queue",DISPATCH_QUEUE_CONCURRENT);
  • GCD暗中同意已经提供了大局的产出队列,供整个应用使用,能够不必手动创造
  • 使用dispatch_get_global_queue 函数获取全局的面世队列

/*
dispatch_queue_priority_t priority : 队列的优先级
unsigned long flags : 参数暂时无用,用0即可
*/
dispatch_queue_t queue = dispatch_get_global_queue(dispatch_queue_priority_t priority,unsigned long flags);
  • 获得全局并发队列

/*
队列的优先级有:
     DISPATCH_QUEUE_PRIORITY_DEFAULT: 默认(中)
     DISPATCH_QUEUE_PRIORITY_HIGH:优先级最高
     DISPATCH_QUEUE_PRIORITY_LOW:低
     DISPATCH_QUEUE_PRIORITY_BACKGROUND:优先级最低,后台优先级
*/
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
  • 交互队列

    • GCD提供了二种得到并行队列的路径

      • 使用dispatch_queu_create函数创制dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);label:表示队列的称号att:表示队列的门类,依照这些装置决断是相互队列依旧串行队列(DISPATCH_QUEUE_CONCU帕杰罗RENT表示并行队列)

      • 使用dispatch_get_global_queue函数获得全局的产出队列(那几个是GCD提供的)
        dispatch_get_global_queue(dispatch_queue_prority_t priority, unsigned long flags);priority:队列的优先级(分为高,私下认可,低,后台)flag:此参数一时半刻无用,用0就可以

  • 串行队列

    • GCD提供了三种得到串行队列的路线

      • 使用dispatch_queue_create函数成立串行队列dispatch_queue_create(const char *label, dispatch_queue_attr_t attr);label:表示该队列的名字attr:表示队列的品质,依据这一个装置推断是相互队列依旧串行队列(DISPATCH_QUEUE_SERIAL或者NULL表示串行队列)
    • 选择主队列(与主线程相关联的行列)

      • 主队列是GCD自带的一种新鲜的串行队列
      • 放置到主队列的任务,都会在主线程中实践
      • 使用dispatch_get_main_queue()获得主队列
//queue:队列;block:任务void dispatch_sync(dispatch_queue_t queue,dispatch_block_t block);

澳门葡京备用网址,4.2.串行队列

  • GCD中猎取串行有2种途径

    • 使用dispatch_queue_create 函数创造串行队列

// 创建串行队列 (队列类型传递 NULL 或者DISPATCH_QUEUE_SERIAL)
dispatch_queue_t queue = dispatch_queue_create("com.WenJim.queue",NULL);
  • 采取主队列 (跟主线程相关联的队列)
    • 主队列是GCD自带的一种特有的串行队列
    • 放在主队列中的职务,都会停放主线程实践
    • 使用 dispatch_get_main_queue() 获得主队列

工程模板:CGD queue

  • 用异步的方法实行职责:能够在新的线程中实践职责,具有开启新线程的工夫

5. 因为有出现队列,串行队列2种队列和一块推行,异步施行三种实行格局,所以有以下组合

5.1 异步函数+并发队列
5.2 异步函数+串行队列
5.3 同步函数 + 并发队列
.54 联合举行函数+串行队列

上述各类是是平常使用的整合,下边2种存在于主队列中的组合,不经常用到

5.5 异步函数 + 主队列
5.6 同步函数 + 主队列

  • 各样队列组合的履行职能
Tables 并发队列 手动创建的串行队列 主队列
同步(sync) 没有开启新线程,串行执行任务 没有开启新线程,串行执行任务 没有开启新线程,串行执行任务
异步(async) 有开启新线程,并发执行任务 有开启新线程,串行 , 执行任务 没有开启新线程,串行执行任务
  • 注意点
  • 动用sync函数往当前串行队列中加上职责,会卡住当前的串行队列
- touchBegan:touches withEvent:(UIEvent *)event { //[self concurrentSync]; //[self concurrentAsync]; //[self globalSync]; //[self globalAsync]; //[self mainSync];//死锁 //[self serialSync];}#pragma mark - 并发队列 + 同步任务:没有启动新的线程,任务是逐个执行的- concurrentSync { //创建并发队列 dispatch_queue_t queue= dispatch_queue_create("myQueue",DISPATCH_QUEUE_CONCURRENT); //在队列里面添加任务 //同步任务 dispatch_sync(queue, ^{ for (int i = 0; i< 5; i++) { NSLog(@"===1===%@", [NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (int i = 0; i< 5; i++) { NSLog(@"===2===%@", [NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (int i = 0; i< 5; i++) { NSLog(@"===3===%@", [NSThread currentThread]); } });}#pragma mark - 并发队列 + 异步任务- concurrentAsync { //创建并发队列 dispatch_queue_t queue= dispatch_queue_create("Queue",DISPATCH_QUEUE_CONCURRENT); //异步任务 dispatch_async(queue, ^{ for (int i = 0; i< 5; i++) { NSLog(@"===1===%@", [NSThread currentThread]); } }); dispatch_async(queue, ^{ for (int i = 0; i< 5; i++) { NSLog(@"===2===%@", [NSThread currentThread]); } }); dispatch_async(queue,^{ for (int i = 0; i< 5; i++) { NSLog(@"===3===%@", [NSThread currentThread]); } });}#pragma mark - 全局队列 + 同步任务:没有启动新的线程,任务是逐个执行的- globalSync { //创建全局队列 dispatch_queue_t queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //同步任务 dispatch_sync(queue, ^{ for (int i = 0; i< 5; i++) { NSLog(@"===1===%@", [NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (int i = 0; i< 5; i++) { NSLog(@"===2===%@", [NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (int i = 0; i< 5; i++) { NSLog(@"===3===%@", [NSThread currentThread]); } });}#pragma mark - 全局队列 + 异步任务:开启了新的线程,任务是并发执行的- globalAsync { //创建全局队列 dispatch_queue_t queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //异步任务 dispatch_async(queue, ^{ for (int i = 0; i< 5; i++) { NSLog(@"===1===%@", [NSThread currentThread]); } }); dispatch_async(queue, ^{ for (int i = 0; i< 5; i++) { NSLog(@"===2===%@", [NSThread currentThread]); } }); dispatch_async(queue,^{ for (int i = 0; i< 5; i++) { NSLog(@"===3===%@", [NSThread currentThread]); } });}#warning - 死锁#pragma mark - 主队列 + 同步任务:卡死了!!!死锁- mainSync { //创建主队列 dispatch_queue_t queue = dispatch_get_main_queue(); //同步任务 dispatch_sync(queue, ^{ for (int i = 0; i< 5; i++) { NSLog(@"===1===%@", [NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (int i = 0; i< 5; i++) { NSLog(@"===2===%@", [NSThread currentThread]); } }); dispatch_sync(queue, ^{ for (int i = 0; i< 5; i++) { NSLog(@"===3===%@", [NSThread currentThread]); } });}#pragma mark - 主队列 + 异步队列:没有开启新的线程,任务是逐个完成的- serialSync { //创建主队列 dispatch_queue_t queue = dispatch_queue_create("queue", NULL); //异步任务 dispatch_async(queue, ^{ for (int i = 0; i< 5; i++) { NSLog(@"===1===%@", [NSThread currentThread]); } }); dispatch_async(queue, ^{ for (int i = 0; i< 5; i++) { NSLog(@"===2===%@", [NSThread currentThread]); } }); dispatch_async(queue,^{ for (int i = 0; i< 5; i++) { NSLog(@"===3===%@", [NSThread currentThread]); } });}

#pragma mark - 线程间的通信- downloadImage { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //耗时操作 NSURL *url = [NSURL URLWithString:@""]; NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:data]; //回归到主线程 dispatch_async(dispatch_get_main_queue(), ^{ //显示图片; UIImageView *imageView = [[UIImageView alloc]init]; imageView.image = image; }); });}

6.便于模糊的术语

  • 有4个术语相比较轻易混淆视听:同步、异步、并发、串行

    • 联合和异步首要影响:能还是不能够展开新线程

      • 手拉手:只好在当下线程中推行任务,不辜负有开启新线程的工夫
      • 异步:能够在新线程中实施职务,具有开启新线程的本领
    • 出现和串行首要影响:职责的施行措施

      • 并发:允许多少个任务并发(同一时候)实施
      • 串行:二个职务试行完成后,再实施下贰个职务

  • 主队列:
    • 主队列特点:假使主队列开掘脚下主线程有职责在进行,那么主队列会暂停调用队列中的职责,直到主线程空闲停止

上面是代码贴出来

//
//  ViewController.m
//  GCD的基本使用
//
//  Created by wenjim on 17/4/10.
//  Copyright © 2017年 WenJim. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic,strong) UIButton * clickBtn;

@end

@implementation ViewController

-(UIButton *)clickBtn
{
    if (!_clickBtn) {
        _clickBtn = [UIButton buttonWithType:UIButtonTypeCustom];
        _clickBtn.frame = CGRectMake(self.view.bounds.size.width / 2 - 40, self.view.bounds.size.height / 2 - 10, 80, 20);
        [_clickBtn setTitle:@"开始" forState:UIControlStateNormal];
        [_clickBtn setTitleColor:[UIColor redColor] forState:UIControlStateNormal];
        [_clickBtn addTarget:self action:@selector(setclickBtn:) forControlEvents:UIControlEventTouchUpInside];

    }
    return _clickBtn;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    [self setUpAllControls];
}

#pragma mark - UI控件布局
-(void)setUpAllControls
{
    [self.view addSubview:self.clickBtn];
}

-(void)setclickBtn:(UIButton *)clickBtn
{
    NSLog(@"开始");
    // 异步函数+并发队列
//    [self asyncConcurrent];

    // 异步函数+串行队列
//    [self asyncSerial];

    // 同步函数 + 并发队列
//    [self syncConcurrent];

    // 同步函数+串行队列
//    [self syncSerial];

    // 异步函数 + 主队列
//    [self asyncMain];

    // 同步函数 + 主队列
//    [self syncMain];
    // 同步函数 + 主队列 在子线程调用的话,就不会形成死锁
    [NSThread detachNewThreadSelector:@selector(syncMain) toTarget:self withObject:nil];
}

#pragma mark - 异步函数+并发队列:会开启多条线程,队列中的任务是异步执行(并发执行)
-(void)asyncConcurrent
{
    // 1. 创建队列
    /*
     第一个参数(const char *_Nullable label):C语言的字符串,标签
     第二个参数(dispatch_queue_attr_t  _Nullable attr):队列的类型
                    DISPATCH_QUEUE_CONCURRENT:并发
                    DISPATCH_QUEUE_SERIAL:串行
     */
//    dispatch_queue_t queue = dispatch_queue_create("com.xiaoningle.download", DISPATCH_QUEUE_CONCURRENT);

    //获取全局并发队列(本身就存在队列)
    /*
    优先级
     DISPATCH_QUEUE_PRIORITY_DEFAULT: 默认(中)
     DISPATCH_QUEUE_PRIORITY_HIGH:优先级最高
     DISPATCH_QUEUE_PRIORITY_LOW:低
     DISPATCH_QUEUE_PRIORITY_BACKGROUND:优先级最低,后台优先级

     第一个参数: 优先级
     第二个参数:
     */
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    // 2.1 封装任务
    // 2.2 添加任务到队列中
    /*
     第一个参数:队列
     第二个参数:block 要执行的任务
     */
    dispatch_async(queue, ^{
        NSLog(@"download -- %@",[NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"download2 -- %@",[NSThread currentThread]);
    });

    dispatch_async(queue, ^{
        NSLog(@"download3 -- %@",[NSThread currentThread]);
    });
}

#pragma mark - 异步函数+串行队列:会开一条线程,队列中的任务是串行执行
-(void)asyncSerial
{
    // 1.创建队列
    dispatch_queue_t queue = dispatch_queue_create("download", DISPATCH_QUEUE_SERIAL);

    // 2.封装操作
    dispatch_async(queue, ^{

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

    });

    dispatch_async(queue, ^{

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

    });

    dispatch_async(queue, ^{

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

    });
}

#pragma mark - 同步函数+并发队列:不会开线程,任务是串行执行的
-(void)syncConcurrent
{
    // 1.创建队列
    dispatch_queue_t queue = dispatch_queue_create("download", DISPATCH_QUEUE_CONCURRENT);

    // 2.封装操作
    dispatch_sync(queue, ^{
        NSLog(@"download -- %@",[NSThread currentThread]);

    });

    dispatch_sync(queue, ^{

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

    });

    dispatch_sync(queue, ^{

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

    });
}

#pragma mark - 同步函数+串行队列:不会开线程,任务是串行执行的
-(void)syncSerial
{
    // 1.创建队列
    dispatch_queue_t queue = dispatch_queue_create("download", DISPATCH_QUEUE_SERIAL);

    // 2.封装操作
    dispatch_sync(queue, ^{
        NSLog(@"download -- %@",[NSThread currentThread]);

    });

    dispatch_sync(queue, ^{

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

    });

    dispatch_sync(queue, ^{

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

    });
}

#pragma mark - 异步函数 + 主队列:所有任务都在主线程中执行,不会开线程
-(void)asyncMain
{
    // 1. 获得主队列
    dispatch_queue_t queue = dispatch_get_main_queue();

    // 2. 异步函数
    dispatch_async(queue, ^{

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

    });

    dispatch_async(queue, ^{

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

    });

    dispatch_async(queue, ^{

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

    });

}

#pragma mark - 同步函数 + 主队列:死锁
-(void)syncMain
{
    // 1. 获得主队列
    dispatch_queue_t queue = dispatch_get_main_queue();
    NSLog(@"start------");
    // 2. 同步函数
    // 立刻马上执行,如果我没有执行完毕,那么后面的也别想执行
    /*
     主队列特点:如果主队列发现当前主线程有任务在执行,那么主队列会暂停调用队列中的任务,直到主线程空闲为止
     */
    dispatch_sync(queue, ^{

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

    });

    dispatch_sync(queue, ^{

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

    });

    dispatch_sync(queue, ^{

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

    });
    NSLog(@"end------");
}

@end
  • iOS常见的推迟施行有2种方法
  • 调用NSObject的方法[self perform selector:@selector withObject:nil afterDelay:2.0];
  • 使用GCD函数
//queue:队列;block:任务void dispatch_async(dispatch_queue_t queue,dispatch_block_t block);

GCD中的队列能够分成两大门类:

 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (2.0* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ //2秒后异步执行这里的代码... });
  • 并发队列(concurrent dispatch
    queue):能够让队列职分并发实践(自动开启八个线程同偶然候实行职务),并发功效唯有在异步函数(dispatch_asyns)中才使得

    • GCD私下认可已经提供了大局的出现队列,提供全数应用使用,没有须求手动创制。

      dispatch_queue_t dispatch_get_global_queue(dispatch_queue_tpriority,unsigned long flags);//priority:队列的优先级,flags:此参数暂时没有使用,传0即可
      
  • 串行队列(serial dispatch
    queue):让职责三个接着贰个地实行(二个职分试行达成后,在实践下八个职务)。GCD有二种办法获得串行队列

    • 使用dispatch_queue_create函数手动创设串行队列

    dispatch_queue_t dispatch_queue_create(const char*label,dispatch_queue_create_attr_t attr);//label:队列名称,attr:队列属性,一般用NULL即可
    
    • 利用主队列(跟主线程相关的队列):主队列是GCD中的自带的一种特殊的串行队列,放在主队列中的职责,都会安置主线程中实行。

    dispatch_queue_t dispatch_get_main_queue;
    
     *注意*: 1. //主队列(添加到主队列中的任务,都会自动添加到主线程中执行) dispatch_queue_t queue = dispatch_get_main_queue(); 2. //添加任务到主队列中异步执行,该异步功能失效 dispatch_async(queue,^{任务}); 3. //添加任务到主队列中同步执行,改同步功能会卡死 Dispatch_sync(queue,^{任务});
    
  • 一回性代码
  • 使用dispatch_once函数能担保某段代码在程序运营进程中只被实行1次

  • 一齐和异步首要影响能还是无法拉开新的线程:同步在现阶段线程中试行职责,不具有别开启新线程的力量;异步能在新线程中实行职责,具有开启新线程的才干

    dispatch_sync: 联手,不持有开启线程的力量

    dispatch_async:异步,具备开启线程的力量

  • 现身和串行主要影响职务的举办措施:并发是多个职分同期施行;串行是二个实践完结后,在实践下贰个职责。

    //获得全局的并发队列dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);//创建一个串行队列dispatch_queue_t queue = dispatch_queue_create("name.queue",NULL);//主队列(添加到主队列中的任务,都会自动方法主线程中执行)dispatch_queue_t queue = dispatch_get_main_queue();
    
 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ //只执行1次的代码(这里面默认是线程安全的) });
  1. 一路函数+主队列
  • 队列组有这么1种供给首先:分别异步实施2个耗费时间的操作其次:等2个异步操作都实践完结后,再回去主线程实施操作假如想赶快地促成上述急需,能够设想用队列组

-syncMain{ NSLog; dispatch_queue_t queue = dispatch_get_main_queue(); dispatch_sync(queue,^{ NSLog(@"1---%@",[NSThread currentThread]); }); dispatch_sync(queue,^{ NSLog(@"2---%@",[NSThread currentThread]); }); dispatch_sync(queue,^{ NSLog(@"3---%@",[NSThread currentThread]); }); NSLog; //注意:使用sync函数往当前队列中添加任务,会卡住当前的串行队列,除了begin其他都不会被打印。}
 dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //执行1个耗时的异步操作 }); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ //执行1个耗时的异步操作 }); dispatch_group_notify(group, dispatch_get_main_queue(), ^{ //等前面的异步操作都执行完毕后,回到主线程... });

- touchBegan:touches withEvent:(UIEvent *)event { //[self delay]; //[self once]; //[self group];}#pragma mark - 延时操作- delay { //NSObject //[self performSelector:@selector withObject:nil afterDelay:2.0]; //NSTimer //[NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector userInfo:nil repeats:NO]; //GCD dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (2.0 *NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [self run]; });}- run { NSLog;}#pragma mark - 一次操作- once { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog; });}#pragma mark - 多次操作- apply { dispatch_apply(10, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t index){ NSLog(@"===%ld===", index); });}#pragma mark - 队列组- group { //创建组 dispatch_group_t group = dispatch_group_create(); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ for (int i = 0; i< 5; i++) { NSLog(@"===1==="); } }); dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ for (int i = 0; i< 5; i++) { NSLog(@"===1==="); } }); //当1、2完成后,再去执行3 dispatch_group_notify(group, dispatch_get_main_queue(), ^{ NSLog(@"===3==="); });}
  1. 异步函数+主队列

- asyncMain{ dispatch_queue_t queue = dispatch_get_main_queue(); dispatch_async(queue, ^{ NSLog(@"1-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"2-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"3-----%@", [NSThread currentThread]); }); //注意:不会开启新线程。只会在主队列中执行,失去了异步函数的功能。}
  1. 一齐函数+串行队列

-syncSerial{ dispatch_queue_t queue = dispatch_queue_create("com.queue",DISPATCH_QUEUE_SERIAL); dispatch_sync(queue,^{ NSLog(@"1---%@",[NSThread currentThread]); }) dispatch_sync(queue,^{ NSLog(@"2---%@",[NSThread currentThread]); }) dispatch_sync(queue,^{ NSLog(@"3---%@",[NSThread currentThread]); }) //注意:不会开启新的线程,在当前线程执行任务。任务是串行的,执行完一个任务,再执行下一个任务}
  1. 异步函数+串行队列

- asyncSerial{ dispatch_queue_t queue = dispatch_queue_create("com.queue", DISPATCH_QUEUE_SERIAL); dispatch_async(queue, ^{ NSLog(@"1-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"2-----%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"3-----%@", [NSThread currentThread]); }); 注意:会开启新的线程,但是任务是串行的,执行完一个任务,再执行下一个任务}
  1. 联合函数+并发队列

- syncConcurrent{ dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_sync(queue, ^{ NSLog(@"1-----%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"2-----%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"3-----%@", [NSThread currentThread]); }); //注意:不会开启新的线程。串行执行任务。}
  1. 异步函数+并发队列:能够相同的时候拉开多条线程,是最常用的法门

- asyncConcurrent{ // 1.获得全局的并发队列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 2.将任务加入队列 dispatch_async(queue, ^{ for (NSInteger i = 0; i<10; i++) { NSLog(@"1-----%@", [NSThread currentThread]); } }); dispatch_async(queue, ^{ for (NSInteger i = 0; i<10; i++) { NSLog(@"2-----%@", [NSThread currentThread]); } }); dispatch_async(queue, ^{ for (NSInteger i = 0; i<10; i++) { NSLog(@"3-----%@", [NSThread currentThread]); } }); 
全局并发队列 手动创建串行队列 主队列
同步 不会开启新线程串行执行任务 没有开启新线程串行执行任务 没有开启新线程串行执行任务会卡死
异步 有开启新线程并发执行任务 有开启新线程串行执行任务 没有开启新线程串行,执行任务

用法一

// 作用:在并行队列中,等待前面的所有并行操作完成,然后执行dispatch_barrier_async中的操作,然后恢复原有执行状态,继续并行执行void dispatch_barrier_async(dispatch_queue_t queue,dispatch_block_t block);

用法二

//作用:延迟执行void dispatch_after(dispatch_time_t when,dispatch_queue_t queue,dispatch_block_t block);

用法三

//作用:block中的代码块只被执行一次static dispatch_once_t onceToken;dispatch_once(&onceToken,^{ //需要执行的代码块});

用法三

 //作用:文件剪切,快速迭代 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); NSString *from = @"/Users/Anthony/Desktop/From"; NSString *to = @"/Users/Anthony/Desktop/To"; NSFileManager *mgr = [NSFileManager defaultManager]; NSArray *subPaths = [mgr subpathsAtPath:from]; dispatch_apply(subPaths.count, queue, ^(size_t index) { NSString *subPath = subPaths[index]; NSString *fromFullPath = [from stringByAppendingPathComponent:subPath]; NSString *toFullPath = [to stringByAppendingPathComponent:subPath]; [mgr moveItemAtPath:fromFullPath toPath:toFullPath error:nil]; NSLog(@"%@--%@",[NSThread currentThread],subPath); }); 

用法四

//队列组dispatch_queue_t queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);�dispatch_group_t group = dispatch_group_create();//下载图片dispatch_group_async(dispatch_group_t group,dispath_queue_t queue,^{});//(保证执行完组里面的所有任务之后,再执行notify函数里面的block)dispatch_group_notify(dispatch_group_t group,dispatch_queue_t queue,dispatch_block_t block);

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website