//用block只有两种:同步执行/异步执行(参数1:队列;参数二:任务)

dispatch_async(dispatch_get_global_queue(0, 0),^{

});//异步在新的线程中执行任务,具备开启新线程能力,能跳过该代码执行后面代码

dispatch_sync(dispatch_get_global_queue(0, 0), ^{

});//同步:在当前线程中执行任务,不具备开启新线程能力,不能跳过该代码执行后面代码

//队列:并发队列(可以让多个任务同时执行自动开启多个线程同时执行任务,注意:只有在异步时才有效)/串行队列(任务一个接一个按顺序依次执行,即一个任务执行完毕后,在执行下一个任务)

//串行队列

dispatch_queue_t queue1 = dispatch_queue_create("mm", DISPATCH_QUEUE_SERIAL);//串行队列

dispatch_block_t task1 = ^{

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

};//创建任务

dispatch_async(queue1, task1);//串行异步开启新线程,任务按顺序依次执行

dispatch_sync(queue1, task1);//串行同步,不开启新线程,任务按顺序依次执行

//并发队列

dispatch_queue_t queue2 = dispatch_queue_create("mm", DISPATCH_QUEUE_CONCURRENT);//并发队列

dispatch_block_t task2 = ^{

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

};//创建任务

dispatch_async(queue2, task2);//并行异步开启多条线程,任务同时执行(不按顺序)

dispatch_sync(queue2, task2);//并行同步,不开启新线程,任务在当前线程按顺序依次执行

//全局队列(也叫做全局并发队列:)

dispatch_queue_t globalQueue =  dispatch_get_global_queue(0, 0);//全局队列(参数1:服务质量,类似于优先级;参数2:预留参数)

dispatch_block_t globaltask = ^{

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

};//创建任务

dispatch_async(globalQueue,globaltask);//全局异步任务;并行异步开启多条线程,任务同时执行(不按顺序)

dispatch_sync(globalQueue,globaltask);//全局同步任务;并行同步,不开启新线程,任务在当前线程按顺序依次执行

//注意:全局变量就是并发队列;区别:全局队列没有名称,无法跟踪错误,而并发队列可以实现;而且arc中不需要考虑释放内存,dispatch_release不允许调用,在mrc中需要手动释放内存,并发队列是creat出来的,在mrc中见到creat就要release,全局队列不需要release(只有一个,类似单例);一般我们使用全局队列;

//主队列(也叫全局串行队列:不创建新线程,主队列里的任务一定在主线程完成,而且必须在主线程空闲时才能执行主队列里的任务)

dispatch_queue_t mainQueue =  dispatch_get_main_queue();//主队列(就是串行队列)

dispatch_block_t maintask = ^{

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

};//创建任务

dispatch_async(mainQueue,maintask);//主队列异步:在主线程执行,任务依次按顺序执行

dispatch_sync(mainQueue,maintask);//主队列同步:(死锁:原因是互相等待造成死锁)在主线程执行

//死锁原因:由于主线程执行代码是按从上到现依次执行方式,所以当代码按顺序执行到主队列时,主线程停下来等待主队列执行队列里的代码;而主队列执行代码条件是只有当主线程空闲时才能执行,所以主队列等待主线程执行完毕空闲下来;这样就导致主队列与主线程相互等待.程序无法继续进行,造成死锁.

//死锁解决方法:就是将主队列同步任务放在一个全局异步队列中去.这样使得主线程得以执行完毕空闲下来,这样就满足了主队列执行条件,主队列中的代码得以执行,死锁就解开了.(实质就是将主队列任务放到一个异步操作中去,让主队列任务在新线程中去执行)

//GCD使用

//1.同步任务(按顺序执行/彼此依赖)例如:appStore 验证用户密码-扣费-下载应用

//特点:在队列调度做个异步任务前,指定一个同步任务,让所有异步任务都等待同步任务完成,这就是所谓"依赖"关系;

//需求:1.操作耗时,需到子线程执行;2.有依赖关系

dispatch_sync(dispatch_get_global_queue(0, 0), ^{

dispatch_async(dispatch_get_global_queue(0, 0), ^{

[NSThread sleepForTimeInterval:2];

NSLog(@"验证密码");

});

dispatch_async(dispatch_get_global_queue(0, 0), ^{

[NSThread sleepForTimeInterval:2];

NSLog(@"扣费");

});

dispatch_async(dispatch_get_global_queue(0, 0), ^{

[NSThread sleepForTimeInterval:2];

NSLog(@"下载应用");

});

});

//线程间通信

dispatch_async(dispatch_get_global_queue(0, 0), ^{

NSURL *url = [NSURL URLWithString:@""];

NSData *data = [NSData dataWithContentsOfURL:url];

UIImage *image = [UIImage imageWithData:data];

//刷新UI 回到主线程就是使用主队列

dispatch_async(dispatch_get_main_queue(), ^{

UIImageView *imgView = [[UIImageView alloc]initWithImage:image];

});

});

//延时操作(是通过dispatch_after(<#dispatch_time_t when#>, <#dispatch_queue_t queue#>, <#^(void)block#>)实现的,只不过默认使用了主队列.(参数1.等待时间;参数2.执行队列;参数3.执行任务))

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

NSLog(@"等了好久");

});

//调度组

dispatch_group_t group = dispatch_group_create();//创建调度组

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

[NSThread sleepForTimeInterval:2];

NSLog(@"第一首下载成功");

});

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

[NSThread sleepForTimeInterval:2];

NSLog(@"第二首下载成功");

});

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

[NSThread sleepForTimeInterval:2];

NSLog(@"第三首下载成功");

});

//回主队列提醒用户

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

NSLog(@"歌曲下载完成");

});

//调度组实现原理

dispatch_group_t group1 = dispatch_group_create();//创建调度组

dispatch_group_enter(group1);

dispatch_async( dispatch_get_global_queue(0, 0), ^{

[NSThread sleepForTimeInterval:2];

NSLog(@"第一首下载成功");

dispatch_group_leave(group1);

});

dispatch_group_enter(group1);

dispatch_async(dispatch_get_global_queue(0, 0), ^{

[NSThread sleepForTimeInterval:2];

NSLog(@"第二首下载成功");

dispatch_group_leave(group1);

});

dispatch_group_enter(group1);

dispatch_async(dispatch_get_global_queue(0, 0), ^{

[NSThread sleepForTimeInterval:2];

NSLog(@"第三首下载成功");

dispatch_group_leave(group1);

});

//回主队列提醒用户

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

NSLog(@"歌曲下载完成");

});

//一次性执行(用来实现单例)应用场景:音乐播放器,视频播放器,封装网络下载工具类

[UIApplication sharedApplication];

[NSUserDefaults standardUserDefaults];

[NSNotificationCenter defaultCenter];

[NSFileManager defaultManager];

//单例(一种设计模式,特点:只要一创建就一直存在于app中,知道应用程序退出才销毁, static静态区:(一旦创建直到程序退出才销毁));单例不能滥用,原因是其特点决定,一旦创建知道程序退出销毁才释放,占大量内存资源,移动端内存本来就小,因此不能滥用;

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

NSLog(@"一次性执行");

});

//创建单例一般用shared+类名;

/*

1.以前未使用互斥锁,存在线程安全问题,添加互斥锁才安全,但此方法效率没有用一次性执行高

.h中:

+(instancetype)sharad+类名;

.m中:

static id _instanceType;

+(instancetype)sharad+类名

{

@synchronized(self) {

if (_instanceType == nil) {

_instanceType = [[self alloc]init];

}

}

return _instanceType;

}

2.一次性执行

在ARC下:

.h中:

+(instancetype)sharad+类名;

.m中:

static id _instanceType;

+(instancetype)sharad+类名

{

//一次性执行实现单例

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

_instanceType = [[self alloc]init];

});

return _instanceType;

}

调用alloc最终会调用此方法

+ (instancetype)allocWithZone:(struct _NSZone *)zone

{

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

_instanceType = [super allocWithZone:zone];

});

return _instanceType;

}

调用alloc最终会调用此方法(ios7之前要遵循NSCopying协议)

-(id)copyWithZone:(NSZone *)zone

{

return _instanceType;

}

在MRC中.m里需添加以下方法:

-(oneway void)release

{

}

-(instancetype)retain

{

return _instanceType;

}

-(instancetype)autorelease

{

return _instanceType;

}

- (NSUInteger)retainCount

{

return 1;

}

*/

/*提取单例宏,创建 singleton.h文件

导入头文件

使用.h中  singleton_h(类名)

使用.m中  singleton_m(类名)

#if __has_feature(objc_arc) //ARC

//.h 拼接参数使用##

#define singleton_h(name) +(instancetype)sharad##name;

//.m 宏里面换行

#define singleton_m(name) static id _instanceType;\

+(instancetype)sharad##name\

{\

static dispatch_once_t onceToken;\

dispatch_once(&onceToken, ^{\

_instanceType = [[self alloc]init];\

});\

return _instanceType;\

}\

+ (instancetype)allocWithZone:(struct _NSZone *)zone\

{\

static dispatch_once_t onceToken;\

dispatch_once(&onceToken, ^{\

_instanceType = [super allocWithZone:zone];\

});\

return _instanceType;\

}\

-(id)copyWithZone:(NSZone *)zone\

{\

return _instanceType;\

}

#else //MRC

//.h 拼接参数使用##

#define singleton_h(name) +(instancetype)sharad##name;

//.m 宏里面换行

#define singleton_m(name) static id _instanceType;\

+(instancetype)sharad##name\

{\

static dispatch_once_t onceToken;\

dispatch_once(&onceToken, ^{\

_instanceType = [[self alloc]init];\

});\

return _instanceType;\

}\

+ (instancetype)allocWithZone:(struct _NSZone *)zone\

{\

static dispatch_once_t onceToken;\

dispatch_once(&onceToken, ^{\

_instanceType = [super allocWithZone:zone];\

});\

return _instanceType;\

}\

-(id)copyWithZone:(NSZone *)zone\

{\

return _instanceType;\

}\

-(oneway void)release\

{\

\

}\

-(instancetype)retain\

{\

return _instanceType;\

}\

-(instancetype)autorelease\

{\

return _instanceType;\

}\

- (NSUInteger)retainCount\

{\

return 1;\

}

#endif

*/

GCD总结的更多相关文章

  1. Objective-C三种定时器CADisplayLink / NSTimer / GCD的使用

    OC中的三种定时器:CADisplayLink.NSTimer.GCD 我们先来看看CADiskplayLink, 点进头文件里面看看, 用注释来说明下 @interface CADisplayLin ...

  2. iOS 多线程之GCD的使用

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

  3. 【swift】BlockOperation和GCD实用代码块

    //BlockOperation // // ViewController.swift import UIKit class ViewController: UIViewController { @I ...

  4. 修改版: 小伙,多线程(GCD)看我就够了,骗你没好处!

    多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术.具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能.具有这种能力的系 ...

  5. GCD的相关函数使用

    GCD 是iOS多线程实现方案之一,非常常用 英文翻译过来就是伟大的中枢调度器,也有人戏称为是牛逼的中枢调度器 是苹果公司为多核的并行运算提出的解决方案 1.一次性函数 dispatch_once 顾 ...

  6. hdu1695 GCD(莫比乌斯反演)

    题意:求(1,b)区间和(1,d)区间里面gcd(x, y) = k的数的对数(1<=x<=b , 1<= y <= d). 知识点: 莫比乌斯反演/*12*/ 线性筛求莫比乌 ...

  7. hdu2588 GCD (欧拉函数)

    GCD 题意:输入N,M(2<=N<=1000000000, 1<=M<=N), 设1<=X<=N,求使gcd(X,N)>=M的X的个数.  (文末有题) 知 ...

  8. BZOJ 2820: YY的GCD [莫比乌斯反演]【学习笔记】

    2820: YY的GCD Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1624  Solved: 853[Submit][Status][Discu ...

  9. BZOJ 2818: Gcd [欧拉函数 质数 线性筛]【学习笔记】

    2818: Gcd Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4436  Solved: 1957[Submit][Status][Discuss ...

随机推荐

  1. SQL Server 如何通过SQL语句定位SSRS中的具体报表

    在一些IT技术人员的推广.简单培训后,公司很多部门都有一些非IT技术人员参与开发各自需求的Reporting Service报表.原因很简单,罗列出来的原因大概有这样一些: IT部门的考量: 1:IT ...

  2. 探索逻辑事务 TransactionScope

    一.什么是TransactionScope? TransactionScope即范围事务(类似数据库中的事务),保证事务声明范围内的一切数据修改操作状态一致性,要么全部成功,要么全部失败回滚. MSD ...

  3. Oracle组合索引与回表

    回表 简单来说就是数据库根据索引找到了指定的记录所在行后,还需要根据rowid再次到数据块里取数据的操作. "回表"一般就是指执行计划里显示的"TABLE ACCESS ...

  4. Python 字符串相加问题

    今天在用Python拼接字符串时碰到个问题,从数据库取出来的数据以及获取到的时间等数据拼成了一个字符串a,将字符串a与自定义的字符串b拼接时一直中断,无法继续执行,也没有报错,将数据库取出数据变成自定 ...

  5. [转]MVC5 - ASP.NET Identity登录原理 - Claims-based认证和OWIN

    本文转自:http://www.cnblogs.com/jesse2013/p/aspnet-identity-claims-based-authentication-and-owin.html 在M ...

  6. plain framework 1 网络流 缓存数据详解

    网络流是什么?为什么网络流中需要存在缓存数据?为什么PF中要采用缓存网络数据的机制?带着这几个疑问,让我们好好详细的了解一下在网络数据交互中我们容易忽视以及薄弱的一块.该部分为PF现有的网络流模型,但 ...

  7. LDR、STR指令

    LDR(load register)指令将内存内容加载入通用寄存器 STR(store register)指令将寄存器内容存入内存空间中 #define GPJ0CON 0xE0200240 _sta ...

  8. C#创建Excel(.xls和.xlsx)文件的三种方法

    生成EXCEL文件是经常需要用到的功能,我们利用一些开源库可以很容易实现这个功能. 方法一:利用excellibrary,http://code.google.com/p/excellibrary/ ...

  9. Javascript的this用法及jQuery中$this和$(this)的区别

    this是Javascript语言的一个关键字. 它代表函数运行时,自动生成的一个内部对象,只能在函数内部使用.比如, function test(){ this.x = 1; } 1.this就是全 ...

  10. 【BZOJ 4579】【Usaco2016 Open】Closing the Farm

    http://www.lydsy.com/JudgeOnline/problem.php?id=4579 把时间倒过来,只是加点,并查集维护连通块. #include<cstdio> #i ...