前言

GCD

全称 Grand Central DisPath NSOperation便是基于GCD的封装

基础知识

1.GCD的优势

(1)为多核的并行运算提出了解决方案

(2)GCD会自动利用更多的CPU内核 比和双核 四核

(3).GCD自动管理线程的生命周期(创建线程 调度任务 销毁线程)

(4).程序员只需告诉GCD想要执行什么任务 不需要编写任何线程管理代码

2.GCD中有2个核心概念

任务: 执行什么操作

队列: 用来存放任务

3.队列可以分为两大类型

串行队列(Serial Dispatch Queue):只有一个线程,加入到队列中的操作按添加顺序依次执行,一个任务执行完毕后,才能再执行下一个任务。

并发队列(Concurrent Dispatch Queue):有多个线程,操作进来以后他会将这些线程安排在可用的处理器上,同时保证先进来的任务优先处理。

其实在GCD中还有一个特殊队列就是主队列 主队列中永远只有一个线程-主线程 用来执行主线程的操作任务

4.采用GCD做多线程 可以抽象分为二步

(1)找到队列(主队列或串行队列或并行队列)

(2)在队列中用同步或者异步的方式执行任务

5.执行队列中的任务的二种方式

(1)同步 只能在当前线程执行任务 不具备开启新线程的能力--主线程

(2)异步 可以在新的线程中执行任务 具备开启新线程的能力--子线程

下面介绍一下串行 并行 同步 异步

- (void)viewDidLoad {

[super viewDidLoad];

self.view.backgroundColor = [UIColor whiteColor];

// Do any additional setup after loading the view, typically from a nib.

#pragma mark ====串行同步====

//    //1.找到队列 第一个参数:该队列的名字 第二个参数:指定队列的类型

//    dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue",DISPATCH_QUEUE_SERIAL);

//    //2.给队列指定任务 第一个参数:任务在哪个队列中执行 第二个参数:想要执行的操作

//    //asyn是异步 syn是同步

//    dispatch_sync(serialQueue, ^{

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

//    });

//

#pragma mark ====串行异步====

//    dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue",DISPATCH_QUEUE_SERIAL);

//    dispatch_async(serialQueue, ^{

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

//    });

#pragma mark ====并行同步====

//    dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrentQueue",DISPATCH_QUEUE_CONCURRENT);

//    dispatch_sync(concurrentQueue, ^{

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

//    });

#pragma mark ====并行异步====

dispatch_queue_t concurrentQueue = dispatch_queue_create("concurrentQueue",DISPATCH_QUEUE_CONCURRENT);

dispatch_async(concurrentQueue, ^{

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

});

}

此时我们新建一个类来看一下 用GCD的形式来加载网络图片让它显示在self.view上 我这里为它命名为OneImageViewController  效果图以及.m代码如下

#import "OneImageViewController.h"
#define kurl @"http://store.storeimages.cdn-apple.com/8748/as-images.apple.com/is/image/AppleInc/aos/published/images/s/38/s38ga/rdgd/s38ga-rdgd-sel-201601?wid=848&hei=848&fmt=jpeg&qlt=80&op_sharpen=0&resMode=bicub&op_usm=0.5,0.5,0,0&iccEmbed=0&layer=comp&.v=1454777389943"
@interface OneImageViewController ()
{
UIImageView *imageView;
}
@end @implementation OneImageViewController
- (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
/*
1.创建视图
2.创建一个串行队列
3.用异步方式执行队列中的任务
4.加载网络资源
5.回到主线程 更新UI */
//1.创建视图
imageView = [[UIImageView alloc]initWithFrame:CGRectMake(50, 50, 200, 200)];
[self.view addSubview:imageView];
//2.创建一个串行队列
dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);
//3.用异步方式执行队列中的任务
dispatch_async(serialQueue, ^{
//4.加载网络资源
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:kurl]];
UIImage *image = [UIImage imageWithData:data];
//5.回到主线程 dispatch_get_main_queue这个函数 找到主队列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
dispatch_sync(mainQueue, ^{
//6.更新UI
imageView.image = image;
}); }); }
@end

  

利用GCD加载多张网络图片 我在这里给类命名为MoreImageViewViewController 效果图以及.m代码如下

#import "MoreImageViewViewController.h"
#define kurl @"http://store.storeimages.cdn-apple.com/8748/as-images.apple.com/is/image/AppleInc/aos/published/images/s/38/s38ga/rdgd/s38ga-rdgd-sel-201601?wid=848&hei=848&fmt=jpeg&qlt=80&op_sharpen=0&resMode=bicub&op_usm=0.5,0.5,0,0&iccEmbed=0&layer=comp&.v=1454777389943"
@interface MoreImageViewViewController ()
{
int imageIndex;
dispatch_queue_t concurrentQueue; }
@end @implementation MoreImageViewViewController - (void)viewDidLoad {
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.edgesForExtendedLayout = UIRectEdgeNone;
/*
1.创建多个视图
2.找到并行队列
3.给这个并行队列指定多个任务
4.在子线程加载网络资源
5.回到主线程
6.更新UI
*/ imageIndex = ; //1.创建多个视图
for (int row = ; row<; row++) {
for (int list = ; list<; list++) { UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(+list*, +row*, , )]; //imageView.backgroundColor = [UIColor orangeColor]; imageView.tag = imageIndex++; [self.view addSubview:imageView]; }
}
//2.找到并行队列 dispatch_get_global_queue 获取到系统的全局并列队列 //第一个参数:是优先级 第二个参数:保留参数 没用
// dispatch_queue_t concurrentQueue = dispatch_get_global_queue(0, 0); concurrentQueue = dispatch_queue_create("concurrentQueue", DISPATCH_QUEUE_SERIAL); //3.给这个并行队列指定多个任务
for (int index = ; index<; index++) {
dispatch_async(concurrentQueue, ^{
[NSThread sleepForTimeInterval:0.5];
//4.加载网络资源
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:kurl]];
UIImage *image = [UIImage imageWithData:data];
//5.回到主线程
dispatch_sync(dispatch_get_main_queue(), ^{
//6.更新UI
UIImageView *imageView = [self.view viewWithTag:+index];
imageView.image = image;
}); });
} [self controlBtn];
} - (void)controlBtn{ UISegmentedControl *segment = [[UISegmentedControl alloc]initWithItems:@[@"暂停",@"开启",]]; segment.frame = CGRectMake(, , , ); segment.apportionsSegmentWidthsByContent = YES; [self.view addSubview:segment]; [segment addTarget:self action:@selector(clickSegment:) forControlEvents:UIControlEventValueChanged];
} - (void)clickSegment:(UISegmentedControl *)sender { switch (sender.selectedSegmentIndex) { case :{
//暂停队列
dispatch_suspend(concurrentQueue);
}break; case :{
//恢复队列
dispatch_resume(concurrentQueue); }break; }

开发中我们可能会用到线程锁 比如购票抢票这一功能

没线程锁的情况下: 我走进购票大厅,买票的人都没有排队,我好不容易挤到窗口前,正打算掏钱买票的时候,旁边有人已经把钱给了售票员。虽然你的线程已经开始执行买票的方法,但当你去拿票时,也就是将票数减一时,CPU将你的线程给中断,开始执行其他的线程,CPU返回继续执行你的线程的时候,票已经没了。

有线程锁的情况下:* 我走进购票大厅,买票的人都在排队,当我到柜台能保证我买票的关键过程,也就是报站、掏钱、拿票过程不受干扰,我采用线程锁将这个关键过程给锁起来,以保证我能顺利的买到票。

我在这里命名为GCDLockViewController 具体.m代码如下

#import "GCDLockViewController.h"

@interface GCDLockViewController ()
{
NSLock *mylock;
}
@end @implementation GCDLockViewController
- (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor whiteColor];
//实例化一个线程锁
mylock = [NSLock new];
#pragma mark ====线程锁====
__block int ticketNum = 10;
dispatch_queue_t concurrent = dispatch_get_global_queue(0, 0);
for (int index = 0; index<15; index++) {
dispatch_async(concurrent, ^{ // [mylock lock];
// if (ticketNum>0) {
// ticketNum--;
// NSLog(@"还剩%d张票",ticketNum);
// }
// [mylock unlock];
//参数一般是self 与self相关的变量 多个线程同时同时只访问一次
@synchronized(self) {
if (ticketNum>0) {
ticketNum--;
NSLog(@"还剩%d张票",ticketNum);
} } });
} }
@end

 

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 1.全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 2.纯C语言,提供了非常多强大的函数 GCD的优势 GCD是苹果公司为多核的并行运算提出的解决方案 G ...

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

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

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

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

  7. ios多线程之GCD

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

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

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

  9. IOS 多线程之GCD

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

随机推荐

  1. mac下安装tomcat

    在window下面搭建tomcat环境很简单,那是因为我们不熟悉mac系统,当我们习惯了命令行的时候,也是so easy,只要通过以下几个步骤就可以解决,本人亲测可用,不会可以留言. 1.进入apch ...

  2. The network bridge on device VMnet0 is not running

    The network bridge on device VMnet0 is not running. The virtual machine will not be able to communic ...

  3. 应用程序框架实战十三:DDD分层架构之我见

    前面介绍了应用程序框架的一个重要组成部分——公共操作类,并提供了一个数据类型转换公共操作类作为示例进行演示.下面准备介绍应用程序框架的另一个重要组成部分,即体系架构支持.你不一定要使用DDD这样的架构 ...

  4. iOS UIWebView 拦截点击事件(双击缩放)

    在平时的开发中,要使用到webview,但类似微信的webview在数据没有加载完成的时候 双击屏幕,webview不会缩放,其实实现这个功能很简单 代码是用swift写的 class YYSimpl ...

  5. Oracle管理磁盘空间和资源

    1.可恢复的空间分配 2.可移动表空间 3.Oracle段收缩功能 4.Oracle数据库资源管理 Reference 1.可恢复的空间分配 1.1 了解可恢复的空间分配 一般情况,我们发出一个大型数 ...

  6. 使用Executor管理线程

    上一篇博客(第一个并发程序:定义任务和驱动任务)中,我们使用Thread对象启动线程,而java.util.concurrent包的Executor执行器提供了更好的管理Thread对象的方法,从而简 ...

  7. Ionic2学习笔记(8):Local Storage& SQLite

    作者:Grey 原文地址: http://www.cnblogs.com/greyzeng/p/5557947.html              Ionic2可以有两种方式来存储数据,Local S ...

  8. Vue.js先入个门看看

    使用vue.js原文介绍:Vue.js是一个构建数据驱动的web界面库.Vue.js的目标是通过尽可能简单的API实现响应式数据绑定和组合的视图组件.vue.js上手非常简单,先看看几个例子: 例一: ...

  9. 使用NW.js封装微信公众号菜单编辑器为桌面应用

    开发微信公众号的朋友都会遇到一个常见的需求就是修改自定义菜单,如果每个人都去开发这个不经常使用的功能确实有点浪费时间.前段时间在github上找到一个仿企业号的菜单编辑界面,结合微信的C# SDK开发 ...

  10. jsp页面显示问题

    一.在jsp页面的表格中,如果有表格中的某一个元素 内容太长,需要截取显示,方法如下: <%@ taglib prefix="fn" uri="http://jav ...