GCD总结
//用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总结的更多相关文章
- Objective-C三种定时器CADisplayLink / NSTimer / GCD的使用
OC中的三种定时器:CADisplayLink.NSTimer.GCD 我们先来看看CADiskplayLink, 点进头文件里面看看, 用注释来说明下 @interface CADisplayLin ...
- iOS 多线程之GCD的使用
在iOS开发中,遇到耗时操作,我们经常用到多线程技术.Grand Central Dispatch (GCD)是Apple开发的一个多核编程的解决方法,只需定义想要执行的任务,然后添加到适当的调度队列 ...
- 【swift】BlockOperation和GCD实用代码块
//BlockOperation // // ViewController.swift import UIKit class ViewController: UIViewController { @I ...
- 修改版: 小伙,多线程(GCD)看我就够了,骗你没好处!
多线程(英语:multithreading),是指从软件或者硬件上实现多个线程并发执行的技术.具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能.具有这种能力的系 ...
- GCD的相关函数使用
GCD 是iOS多线程实现方案之一,非常常用 英文翻译过来就是伟大的中枢调度器,也有人戏称为是牛逼的中枢调度器 是苹果公司为多核的并行运算提出的解决方案 1.一次性函数 dispatch_once 顾 ...
- hdu1695 GCD(莫比乌斯反演)
题意:求(1,b)区间和(1,d)区间里面gcd(x, y) = k的数的对数(1<=x<=b , 1<= y <= d). 知识点: 莫比乌斯反演/*12*/ 线性筛求莫比乌 ...
- hdu2588 GCD (欧拉函数)
GCD 题意:输入N,M(2<=N<=1000000000, 1<=M<=N), 设1<=X<=N,求使gcd(X,N)>=M的X的个数. (文末有题) 知 ...
- BZOJ 2820: YY的GCD [莫比乌斯反演]【学习笔记】
2820: YY的GCD Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1624 Solved: 853[Submit][Status][Discu ...
- BZOJ 2818: Gcd [欧拉函数 质数 线性筛]【学习笔记】
2818: Gcd Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 4436 Solved: 1957[Submit][Status][Discuss ...
随机推荐
- MySQL 临时表
MySQL 临时表在我们需要保存一些临时数据时是非常有用的.临时表只在当前连接可见,当关闭连接时,Mysql会自动删除表并释放所有空间. 临时表在MySQL 3.23版本中添加,如果你的MySQL版本 ...
- 萌新笔记——git的问题(error: object file .git/objects/* is empty...)的解决方案及对git版本库文件的了解
由于操作不当,导致git版本库出了大问题,如下所示: error: object file .git/objects/8b/61d0135d3195966b443f6c73fb68466264c68e ...
- android r.styleable是什么或报错
r.styleable 是自定义控件 自定义控件写好的后,需要在res-value-attrs.xml中定义,如: <declare-styleable name="SlidingMe ...
- Linux 信号(二)—— signal 函数
弗洛伊德认为:要解决这些苦恼,当事人就要通过回忆并理解自己早期的童年经历,来获得对潜意识冲突的顿悟.弗洛伊德的疗法被称为“精神分析” (psychoanalysis),在 20 世纪的很长一段时间被心 ...
- 当我们在谈论kmeans(2)
本稿为初稿,后续可能还会修改:如果转载,请务必保留源地址,非常感谢! 博客园:http://www.cnblogs.com/data-miner/ 其他:建设中- 当我们在谈论kmeans(2 ...
- 极路由2(极贰)在OpenWrt下定制自己的ss服务
默认刷入的OpenWrt带的ss, 只有ss-redir服务, 但是在实际使用中, 很多时候还是希望访问直接通过正常网关, 只有少部分访问需要通过ss, 所以希望能配置成为ss-local服务. 在保 ...
- 【WPF】值是枚举的RadioButton 绑定问题
源 1.RadioButton 2.IValueConverter 3.枚举 xaml实现 <RadioButton Content="单打热身" GroupName=&qu ...
- jquery版固定边栏滚动特效
<!DOCTYPE html><html> <head> <meta charset="UTF-8"> <title>& ...
- css3-无缝滚动
@keyframes 规则用于创建动画.在 @keyframes 中规定某项 CSS 样式,就能创建由当前样式逐渐改为新样式的动画效果. 动画的名称和运行所需时间是必须的 帧动画:将动画名称赋给选择器 ...
- 并发包的线程池第一篇--ThreadPoolExecutor执行逻辑
学习这个很长时间了一直没有去做个总结,现在大致总结一下并发包的线程池. 首先,任何代码都是解决问题的,线程池解决什么问题? 如果我们不用线程池,每次需要跑一个线程的时候自己new一个,会导致几个问题: ...