什么是GCD

  1.全称是Grand Central Dispatch,可译为“牛逼的中枢调度器”

  2.纯C语言,提供了非常多强大的函数

GCD的优势

  1. GCD是苹果公司为多核的并行运算提出的解决方案
  2. GCD会自动利用更多的CPU内核(比如双核、四核)
  3. GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
  4. 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码

任务和队列

GCD中有2个核心概念

  1. 任务:执行什么操作
  2. 队列:用来存放任务

GCD的使用就2个步骤,首先确定定制任务(确定想做的事情),然后将任务添加到队列中,GCD会自动将队列中的任务取出,放到对应的线程中执行(任务的取出遵循队列的FIFO原则:先进先出,后进后出)

执行任务

GCD中有2个用来执行任务的函数

  1.用同步的方式执行任务

dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

//queue:队列

//block:任务

  2.用异步的方式执行任务

dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

同步和异步的区别

同步:只能在当前线程中执行任务,不具备开启新线程的能力

异步:可以在新的线程中执行任务,具备开启新线程的能力

队列的类型

GCD的队列可以分为2大类型

  1.并发队列(Concurrent Dispatch Queue):可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务),并发功能只有在异步(dispatch_async)函数下才有效

  2.串行队列(Serial Dispatch Queue):让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)

容易混淆的术语

有4个术语比较容易混淆:同步、异步、并发、串行

  • 同步和异步主要影响:能不能开启新的线程
    •   同步:在当前线程中执行任务,不具备开启新线程的能力
    •   异步:在新的线程中执行任务,具备开启新线程的能力
  • 并发和串行主要影响:任务的执行方式
    •   并发:多个任务并发(同时)执行
    •   串行:一个任务执行完毕后,再执行下一个任务

并发队列

  GCD默认已经提供了全局的并发队列,供整个应用使用,不需要手动创建,使用dispatch_get_global_queue函数获得全局的并发队列

dispatch_queue_t dispatch_get_global_queue(

dispatch_queue_priority_t priority, // 队列的优先级

unsigned long flags); // 此参数暂时无用,用0即可

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ); // 获得全局并发队列

  全局并发队列的优先级

#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 // 后台

串行队列

  GCD中获得串行有2种途径

    1.使用dispatch_queue_create函数创建串行队列

dispatch_queue_t

dispatch_queue_create(const char *label, // 队列名称 

dispatch_queue_attr_t attr); // 队列属性,一般用NULL即可

dispatch_queue_t queue = dispatch_queue_create("cn.itcast.queue", NULL); // 创建

dispatch_release(queue); // 非ARC需要释放手动创建的队列

    2.使用主队列(跟主线程相关联的队列)。主队列是GCD自带的一种特殊的串行队列。放在主队列中的任务,都会放到主线程中执行。使用dispatch_get_main_queue()获得主队列

dispatch_queue_t queue = dispatch_get_main_queue();

各种队列的执行效果

线程间通信示例

  • 从子线程回到主线程
dispatch_async(

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{

    // 执行耗时的异步操作...

      dispatch_async(dispatch_get_main_queue(), ^{

        // 回到主线程,执行UI刷新操作

        });

});

延时执行

iOS常见的延时执行有2种方式

  • 调用NSObject的方法
[self performSelector:@selector(run) withObject:nil afterDelay:2.0];

// 2秒后再调用self的run方法
  • 使用GCD函数
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

    // 2秒后执行这里的代码... 在哪个线程执行,跟队列类型有关

});

一次性代码

  • 使用dispatch_once函数能保证某段代码在程序运行过程中只被执行1次
static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

    // 只执行1次的代码(这里面默认是线程安全的)

});

队列组

  假设有这么1种需求。首先,分别异步执行2个耗时的操作;其次,等2个异步操作都执行完毕后,再回到主线程执行操作。如果想要快速高效地实现上述需求,可以考虑用队列组

dispatch_group_t group =  dispatch_group_create();

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

    // 执行1个耗时的异步操作

});

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

    // 执行1个耗时的异步操作

});

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

    // 等前面的异步操作都执行完毕后,回到主线程...

});

单例模式

  1. 单例模式的作用

    •   可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问
    •   从而方便地控制了实例个数,并节约系统资源
  2. 单例模式的使用场合
    •   在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次)
    •   单例模式在ARC\MRC环境下的写法有所不同,需要编写2套不同的代码,可以用宏判断是否为ARC环境
#if __has_feature(objc_arc)

// ARC

#else

// MRC

#endif

  3. 单例模式 - ARC

    •   ARC中,单例模式的实现是在.m中保留一个全局的static的实例
  static id _instance;
    •   重写allocWithZone:方法,在这里创建唯一的实例(注意线程安全)
+ (id)allocWithZone:(struct _NSZone *)zone {

    if (_instance == nil) { // 防止频繁加锁

        @synchronized(self) {

            if (_instance == nil) { // 防止创建多次

  _instance = [super allocWithZone:zone];

            }

        }

    }

    return _instance;

}
    •   提供1个类方法让外界访问唯一的实例
+ (instancetype)sharedMusicTool {

    if (_instance == nil) { // 防止频繁加锁

        @synchronized(self) {

            if (_instance == nil) { // 防止创建多次

               _instance = [[self alloc] init];

            }

        }

    }

    return _instance;

}
    •   实现copyWithZone:方法
- (id)copyWithZone:(struct _NSZone *)zone {

    return _instance;

}

  4.单例模式 – 非ARC

    •   非ARC中(MRC),单例模式的实现(比ARC多了几个步骤)
    •   实现内存管理方法
- (id)retain { return self; }

- (NSUInteger)retainCount { return ; }

- (oneway void)release {}

- (id)autorelease { return self; }

iOS多线程之GCD学习笔记的更多相关文章

  1. iOS多线程之GCD小记

    iOS多线程之GCD小记 iOS多线程方案简介 从各种资料中了解到,iOS中目前有4套多线程的方案,分别是下列4中: 1.Pthreads 这是一套可以在很多操作系统上通用的多线程API,是基于C语言 ...

  2. iOS 多线程之GCD的使用

    在iOS开发中,遇到耗时操作,我们经常用到多线程技术.Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法,只需定义想要执行的任务,然后添加到适当的调度队列 ...

  3. iOS多线程之GCD详解

    GCD(Grand Central Dispatch)是基于C语言开发的一套多线程开发机制.也是目前苹果官方推荐的多线程开发方法.iOS三种多线程开发中GCD是抽象层次最高的.当然用起来也是最简单的. ...

  4. (五十五)iOS多线程之GCD

    GCD的全称为Grand Central Dispatch,翻译为大中央调度,是Apple开发的一个多线程编程解决方法. 进程和线程的概念: 正在进行中的程序被称为进程,负责程序运行的内存分配,每一个 ...

  5. iOS 多线程之GCD的简单使用

    在iOS开发中,遇到耗时操作,我们经常用到多线程技术.Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法,只需定义想要执行的任务,然后添加到适当的调度队列 ...

  6. ios多线程之GCD

    介绍: Grand Central Dispatch 简称(GCD)是苹果公司开发的技术,以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统.这建立在任务并行执行的线程池模式的基础上的.它首 ...

  7. iOS多线程之GCD、OperationQueue 对比和实践记录

    [toc] 简介      在计算的早期,计算机可以执行的最大工作量是由 CPU 的时钟速度决定的.但是随着技术的进步和处理器设计的紧凑化,热量和其他物理约束开始限制处理器的最大时钟速度.因此,芯片制 ...

  8. IOS 多线程之GCD

    参考:http://www.cnblogs.com/wendingding/p/3806821.html <<Objective-C基础教程>> 第二版 一 简介 GCD 全称 ...

  9. IOS多线程之NSOperation学习总结

    NSOperation简介 1.NSOperation的作用 配合使用NSOperation和NSOperationQueue也能实现多线程编程 2.NSOperation和NSOperationQu ...

随机推荐

  1. iOS 细碎知识整理

    1centerX,即x轴的中点 centery,即y轴的中点

  2. tomcat集群配置

    http://www.finereporthelp.com/help/24/1/3/3.html#a:4.1

  3. easyui 上传文件代码

    using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.IO;usi ...

  4. ASP.NET Core文档中Work with Data章节的翻译目录

    作为初学者看了相关的教程,遇到的问题有: 1. 教程不是针对初学者,往往在某一方面教的较深,但并不系统,不适合初学者: 2. 虽然翻译的很顺畅,但是谈了自己较多的开发体会,初学者看着困难,尤其是TOM ...

  5. js 中 continue 与 break 熟练使用

    //break:在循环体中,遇到break,整个循环都结束了,后面的累加操作也不在执行了,并且循环体中,只要遇到break,那么循环体break后面的代码都不在执行了 //continue:在循环体中 ...

  6. robotframework笔记24

    侦听器接口 机器人框架有一个侦听器接口,可以用于接收 对测试执行通知. 示例用法包括 外部测试监控,测试失败时发送邮件消息, 与其他系统进行通信. 侦听器API版本3也使得 它可以修改测试在测试执行和 ...

  7. 《javascript高级程序设计》 第20章 JSON

    20.1 语法 20.1.1 简单值 20.1.2 对象 20.1.3 数组 20.2 解析与序列化 20.2.1 JSON 对象 20.2.2 序列化选项 20.2.3 解析选项 JSON 对象有两 ...

  8. valuestack,stackContext,ActionContext.之间的关系

    者之间的关系如下图所示: relation ActionContext 一次Action调用都会创建一个ActionContext 调用:ActionContext context = ActionC ...

  9. Objective-C:Foundation框架-常用类-NSString全解

    Foundation框架中常用的类有字符串.集合.字典等,这里介绍字符串NSString.本文分别介绍了NSString的创建.从文件里读取NSString字符串.通过函数改变外部的NSString变 ...

  10. struts2视频学习笔记 18(自定义拦截器)

    课时18 自定义拦截 因为struts2中如文件上传,数据验证,封装请求参数到action等功能都是由系统默认的defaultStack中的拦截器实现的,所以我们定义的拦截器需要引用系统默认的defa ...