iOS多线程(二)GCD

GCD

  • 全称是Grand Central Dispatch,“伟大的中枢调度器”
  • GCD是苹果公司为多核的并行运算提出的解决方案
  • 纯C语言,提供了非常多强大的函数

优势

  1. GCD会自动利用更多的CPU内核(比如双核、四核)
  2. GCD会自动管理线程的生命周期(创建线程、调度任务、销毁线程)
  3. 只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码

基本概念

任务和队列

GCD中有2个核心概念

1.任务:执行什么操作

2.队列:用来存放任务

// 1.定制任务:确定想做的事情
// 2.将任务添加到队列中:GCD会自动将队列中的任务取出,放到对应的线程中执行。
Tips:任务的取出遵循队列的FIFO原则:先进先出,后进后出

任务

一、执行任务
 - queue:队列
 - block:任务
// 1.用同步的方式执行任务
dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

// 2.用异步的方式执行任务
dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

// 3.GCD中还有个用来执行任务的函数
// 在前面的任务执行结束后它才执行,而且它后面的任务等它执行完成之后才会执行
dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block);

注意:

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

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

队列

一、并发队列(Concurrent Dispatch Queue)
  • 可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)
  • 并发功能只有在异步(dispatch_async)函数下才有效
// 1.使用dispatch_queue_create函数创建队列
dispatch_queue_t
dispatch_queue_create(const char *label, // 队列名称
dispatch_queue_attr_t attr); // 队列的类型

// 2.创建并发队列
dispatch_queue_t queue = dispatch_queue_create("queue", DISPATCH_QUEUE_CONCURRENT);

// 3.使用dispatch_get_global_queue函数获得全局的并发队列
dispatch_queue_t dispatch_get_global_queue(dispatch_queue_priority_t priority, unsigned long flags);
// dispatch_queue_priority_t priority(队列的优先级 )
// unsigned long flags( 此参数暂时无用,用0即可 )

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

// 5.全局并发队列的优先级
#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 // 后台
二、串行队列(Serial Dispatch Queue)
  • 让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)
// 1.使用dispatch_queue_create函数创建串行队列
// 创建串行队列(队列类型传递NULL或者DISPATCH_QUEUE_SERIAL)
dispatch_queue_t queue = dispatch_queue_create("queue", NULL);

// 2.使用dispatch_get_main_queue()获得主队列
dispatch_queue_t queue = dispatch_get_main_queue();
注意:主队列是GCD自带的一种特殊的串行队列,放在主队列中的任务,都会放到主线程中执行。
三、各种队列的执行效果

特别注意:使用sync函数往当前串行队列中添加任务,会卡住当前的串行队列 (线程卡死)


新手易混淆

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

1.同步和异步主要影响:能不能开启新的线程

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

2.并发和串行主要影响:任务的执行方式

  • 并发:多个任务并发(同时)执行
  • 串行:一个任务执行完毕后,再执行下一个任务

GCD运用

一、线程间通信

从子线程回到主线程
dispatch_async(
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    // 执行耗时的异步操作...
      dispatch_async(dispatch_get_main_queue(), ^{
        // 回到主线程,执行UI刷新操作
        });
});

二、延时执行

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次的代码(这里面默认是线程安全的)
});

四、快速迭代

// 使用dispatch_apply函数能进行快速迭代遍历
dispatch_apply(10, dispatch_get_global_queue(0, 0), ^(size_t index){
    // 执行10次代码,index顺序不确定
});

五、队列组

// 分别异步执行2个耗时的操作、2个异步操作都执行完毕后,再回到主线程执行操作
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(), ^{
    // 等前面的异步操作都执行完毕后,回到主线程...
});

单例模式

作用:

  • 可以保证在程序运行过程,一个类只有一个实例,而且该实例易于供外界访问。从而方便地控制了实例个数,并节约系统资源

使用场合

  • 在整个应用程序中,共享一份资源(这份资源只需要创建初始化1次)

实现过程:

1.重写实现:

  • 创建一个需要单例模式的文件
// 1.在.m中保留一个全局的static的实例
static id _instance;

// 2.重写allocWithZone:方法,在这里创建唯一的实例(注意线程安全)
+ (instancetype)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [super allocWithZone:zone];
    });
    return _instance;
}

// 3.提供1个类方法让外界访问唯一的实例
+ (instancetype)sharedInstance
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        _instance = [[self alloc] init];
    });
    return _instance;
}

// 4.实现copyWithZone:方法
- (id)copyWithZone:(struct _NSZone *)zone
{
    return _instance;
}

2.宏实现:

// .h文件
#define SingletonH(name) + (instancetype)shared##name;

// .m文件
#define SingletonM(name) static id _instance;  + (instancetype)allocWithZone:(struct _NSZone *)zone {     static dispatch_once_t onceToken;     dispatch_once(&onceToken, ^{         _instance = [super allocWithZone:zone];     });     return _instance; }  + (instancetype)shared##name {     static dispatch_once_t onceToken;     dispatch_once(&onceToken, ^{         _instance = [[self alloc] init];     });     return _instance; }  - (id)copyWithZone:(NSZone *)zone {     return _instance; }


单例模式

致谢

感谢您花时间阅读,期待与您的交流。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-27 17:57:33

iOS多线程(二)GCD的相关文章

iOS多线程技术—GCD介绍

iOS多线程技术—GCD介绍 一.简单介绍 1.什么是GCD? 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 2.GCD的优势 GCD是苹果公司为多核的并行运算提出的解决方案 GCD会自动利用更多的CPU内核(比如双核.四核) GCD会自动管理线程的生命周期(创建线程.调度任务.销毁线程) 程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码 3.提示 (1)GCD存在于libdispatch.dylib这个库中,

iOS多线程技术—GCD的用法

iOS多线程技术—GCD的用法 一.主队列介绍 主队列:是和主线程相关联的队列,主队列是GCD自带的一种特殊的串行队列,放在主队列中得任务,都会放到主线程中执行. 提示:如果把任务放到主队列中进行处理,那么不论处理函数是异步的还是同步的都不会开启新的线程. 获取主队列的方式: 1 // 2 // YYViewController.m 3 // 12-GCD的基本使用(主队列) 4 // 5 // Created by 孔医己 on 14-6-25. 6 // Copyright (c) 2014

多线程二(GCD)代码笔记

// // TWFXViewController.h // Demo_GCD // // Created by Lion User on 12-12-11. // Copyright (c) 2012年 Lion User. All rights reserved. // #import <UIKit/UIKit.h> @interface TWFXViewController : UIViewController @property (retain, nonatomic) IBOutlet

iOS多线程开发——GCD的使用与多线程开发浅析(二)

对于iOS多线程开发,我们时刻处于学习之中,在看书中,看文档中,项目开发中,都可以去提高自己.最近刚看完了<Objective-C高级编程 iOS与OS X多线程和内存管理>这本书后,对多线程有了更为深入的理解,故在此做一个总结与记录.这本书我已经上传至网盘  https://pan.baidu.com/s/1c2fX3EC ,这本书是iOS开发者必读的书之一,写得很不错,欢迎大家下载阅读.书的封面如下,故也称狮子书: . (1)多线程会遇到的问题 . 多线程会出现什么问题呢?当多个线程对同一

iOS多线程 NSThread/GCD/NSOperationQueue

http://www.cnblogs.com/kenshincui/p/3983982.html iOS开发系列--并行开发其实很容易 2014-09-20 23:34 by KenshinCui, 9738 阅读, 19 评论, 收藏,  编辑 --多线程开发 概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操作只能一步步按顺序逐个执行.改变这种

iOS多线程(GCD NSOperation NSThread)

进程:进程是指在系统中正在运行的一个应用程序,每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内. 线程:1个进程要想执行任务,必须得有线程(每1个进程至少要有1条线程)线程是进程的基本执行单元,一个进程(程序)的所有任务都在线程中执行,比如使用酷狗播放音乐.使用迅雷下载电影,都需要在线程中执行.1个线程中任务的执行是串行的,如果要在1个线程中执行多个任务,那么只能一个一个地按顺序执行这些任务,也就是说,在同一时间内,1个线程只能执行1个任务,比如在1个线程中下载3个文件(分别是文

iOS 多线程编程gcd全面系统认识

这两天在看<OC高级编程-多线程编程和内存管理>日本人写的那本,该书对arc,block和gcd有了更深层次的解读,非常不错.现在总结一下gcd相关的知识.有关arc和block的参考arc   参考block 网上很多博客都对gcd有过讲解,很多是对gcd的全局队列,主线程队列,创建队列等等,做了单方面的描述,不是很全面系统.下面我们将学习一下系统得gcd.本文主要分为下面几个要点,前几个好点比较好理解,最后可能理解起来有些费劲! ● 什么是gcd,iOS为什么要用多线程 ● 创建线程,序列

ios 多线程小结----- GCD篇

//3 GCD(充分利用设备的多盒)-------------屏蔽了线程,只能看见任务 队列步骤两步,定制任务,将任务添加到队列.GCD将添加的任务,放到线程中去执行,自动执行,自动释放原则:先进先出,先添加的任务先执行,有别于栈的先进后出,先添加的任务后执行 -------GCD--- GCD有两个用来执行任务的函数:同步函数,异步函数同步:按顺序执行任务,同一条线程执行(不开线程)异步:同时执行任务(开启新线程) 同步,异步,并发,串行同步:当前线程执行,不具备开启新线程的能力异步:在新线程

iOS多线程技术---GCD

下面这个链接的GCD讲的很好,做个备忘. 1,将GCD的各种原理,分析的比较透彻: http://www.dreamingwish.com/dream-2012/gcdgrand-central-dispatch%E6%95%99%E7%A8%8B.html 2,唐巧(前网易有道员工),简洁明了的使用示例: http://blog.devtang.com/blog/2012/02/22/use-gcd/

iOS 多线程之 GCD 的基本使用

什么是GCD 全称Grand Central Dispatch 中暑调度器 纯C语言 提供了很多强大的函数 GCD 的优势 GCD是苹果公司为多核的并行运算提出的解决方案 GCD会自动利用更多的CPU内核(比如 双核 四核) GCD会自动管理线程的生命周期 (创建线程 调度任务 销毁线程) 程序员只需要告诉GCD想要执行什么任务 不需要编写任何线程管理的代码 GCD的核心概念任务和队列 任务: 需要执行的操作 队列:用来存放任务 调度任务 安排任务在哪个线程中执行 GCD的使用步骤 1 定制任务