GCD编程(封装GCD)
//GCDGroup 类
@interface GCDGroup : NSObject
@property (strong, nonatomic, readonly) dispatch_group_t dispatchGroup;
#pragma 初始化以及释放
- (instancetype)init;
#pragma 使用方法
- (void)enter;
- (void)leave;
- (void)wait;
- (BOOL)wait:(int64_t)delta;
@end
#import "GCDGroup.h"
@interface GCDGroup ()
@property (strong, nonatomic, readwrite) dispatch_group_t dispatchGroup;
@end
@implementation GCDGroup
- (instancetype)init {
self = [super init];
if (self) {
self.dispatchGroup = dispatch_group_create();
}
return self;
}
- (void)enter {
dispatch_group_enter(self.dispatchGroup);
}
- (void)leave {
dispatch_group_leave(self.dispatchGroup);
}
- (void)wait {
dispatch_group_wait(self.dispatchGroup, DISPATCH_TIME_FOREVER);
}
- (BOOL)wait:(int64_t)delta {
return dispatch_group_wait(self.dispatchGroup,
\
;
}
@end
//GCDQueue 类
@class GCDGroup;
@interface GCDQueue : NSObject
@property (strong, readonly, nonatomic) dispatch_queue_t dispatchQueue;
+ (GCDQueue *)mainQueue;
+ (GCDQueue *)globalQueue;
+ (GCDQueue *)highPriorityGlobalQueue;
+ (GCDQueue *)lowPriorityGlobalQueue;
+ (GCDQueue *)backgroundPriorityGlobalQueue;
#pragma 便利的构造方法
+ (void)executeInMainQueue:(dispatch_block_t)block;
+ (void)executeInGlobalQueue:(dispatch_block_t)block;
+ (void)executeInHighPriorityGlobalQueue:(dispatch_block_t)block;
+ (void)executeInLowPriorityGlobalQueue:(dispatch_block_t)block;
+ (void)executeInBackgroundPriorityGlobalQueue:(dispatch_block_t)block;
+ (void)executeInMainQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec;
+ (void)executeInGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec;
+ (void)executeInHighPriorityGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec;
+ (void)executeInLowPriorityGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec;
+ (void)executeInBackgroundPriorityGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec;
#pragma 初始化以及释放
- (instancetype)init;
- (instancetype)initSerial;
- (instancetype)initConcurrent;
#pragma 使用方法
- (void)execute:(dispatch_block_t)block;
- (void)execute:(dispatch_block_t)block afterDelay:(int64_t)delta;
- (void)waitExecute:(dispatch_block_t)block;
- (void)barrierExecute:(dispatch_block_t)block;
- (void)waitBarrierExecute:(dispatch_block_t)block;
- (void)suspend;
- (void)resume;
#pragma 与GCDGroup相关
- (void)execute:(dispatch_block_t)block inGroup:(GCDGroup *)group;
- (void)notify:(dispatch_block_t)block inGroup:(GCDGroup *)group;
@end
#import "GCDQueue.h"
#import "GCDGroup.h"
static GCDQueue *mainQueue;
static GCDQueue *globalQueue;
static GCDQueue *highPriorityGlobalQueue;
static GCDQueue *lowPriorityGlobalQueue;
static GCDQueue *backgroundPriorityGlobalQueue;
@interface GCDQueue ()
@property (strong, readwrite, nonatomic) dispatch_queue_t dispatchQueue;
@end
@implementation GCDQueue
+ (GCDQueue *)mainQueue {
return mainQueue;
}
+ (GCDQueue *)globalQueue {
return globalQueue;
}
+ (GCDQueue *)highPriorityGlobalQueue {
return highPriorityGlobalQueue;
}
+ (GCDQueue *)lowPriorityGlobalQueue {
return lowPriorityGlobalQueue;
}
+ (GCDQueue *)backgroundPriorityGlobalQueue {
return backgroundPriorityGlobalQueue;
}
+ (void)initialize {
/**
Initializes the class before it receives its first message.
1. The runtime sends the initialize message to classes in a
thread-safe manner.
2. initialize is invoked only once per class. If you want to
perform independent initialization for the class and for
categories of the class, you should implement load methods.
*/
if (self == [GCDQueue self])
{
mainQueue = [GCDQueue new];
mainQueue.dispatchQueue = \
dispatch_get_main_queue();
globalQueue = [GCDQueue new];
globalQueue.dispatchQueue = \
);
highPriorityGlobalQueue = [GCDQueue new];
highPriorityGlobalQueue.dispatchQueue = \
);
lowPriorityGlobalQueue = [GCDQueue new];
lowPriorityGlobalQueue.dispatchQueue = \
);
backgroundPriorityGlobalQueue = [GCDQueue new];
backgroundPriorityGlobalQueue.dispatchQueue = \
);
}
}
- (instancetype)init {
return [self initSerial];
}
- (instancetype)initSerial {
self = [super init];
if (self)
{
self.dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_SERIAL);
}
return self;
}
- (instancetype)initConcurrent {
self = [super init];
if (self)
{
self.dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT);
}
return self;
}
- (void)execute:(dispatch_block_t)block {
dispatch_async(self.dispatchQueue, block);
}
- (void)execute:(dispatch_block_t)block afterDelay:(int64_t)delta
{
// NSEC_PER_SEC
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delta), self.dispatchQueue,
block);
}
- (void)waitExecute:(dispatch_block_t)block {
/*
As an optimization, this function invokes the block on
the current thread when possible.
作为一个建议,这种方法尽量在当前线程池中调用.
*/
dispatch_sync(self.dispatchQueue, block);
}
- (void)barrierExecute:(dispatch_block_t)block {
/*
The queue you specify should be a concurrent queue that you
create yourself using the dispatch_queue_create function.
If the queue you pass to this function is a serial queue or
one of the global concurrent queues, this function behaves
like the dispatch_async function.
使用的线程池应该是你自己创建的并发线程池.假设你传进来的參数为串行线程池
或者是系统的并发线程池中的某一个,这种方法就会被当做一个普通的async操作
*/
dispatch_barrier_async(self.dispatchQueue,
block);
}
- (void)waitBarrierExecute:(dispatch_block_t)block {
/*
The queue you specify should be a concurrent queue that you
create yourself using the dispatch_queue_create function.
If the queue you pass to this function is a serial queue or
one of the global concurrent queues, this function behaves
like the dispatch_sync function.
使用的线程池应该是你自己创建的并发线程池.假设你传进来的參数为串行线程池
或者是系统的并发线程池中的某一个,这种方法就会被当做一个普通的sync操作
As an optimization, this function invokes the barrier block
on the current thread when possible.
作为一个建议,这种方法尽量在当前线程池中调用.
*/
dispatch_barrier_sync(self.dispatchQueue,
block);
}
- (void)suspend {
dispatch_suspend(self.dispatchQueue);
}
- (void)resume {
dispatch_resume(self.dispatchQueue);
}
- (void)execute:(dispatch_block_t)block inGroup:(GCDGroup *)group
{
dispatch_group_async(group.dispatchGroup, self.dispatchQueue,
block);
}
- (void)notify:(dispatch_block_t)block inGroup:(GCDGroup *)group
{
dispatch_group_notify(group.dispatchGroup, self.dispatchQueue,
block);
}
#pragma mark - 便利的构造方法
+ (void)executeInMainQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec
{
[[GCDQueue mainQueue] execute:^{
block();
} afterDelay:NSEC_PER_SEC * sec];
}
+ (void)executeInGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec
{
[[GCDQueue globalQueue] execute:^{
block();
} afterDelay:NSEC_PER_SEC * sec];
}
+ (void)executeInHighPriorityGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec
{
[[GCDQueue highPriorityGlobalQueue] execute:^{
block();
} afterDelay:NSEC_PER_SEC * sec];
}
+ (void)executeInLowPriorityGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec
{
[[GCDQueue lowPriorityGlobalQueue] execute:^{
block();
} afterDelay:NSEC_PER_SEC * sec];
}
+ (void)executeInBackgroundPriorityGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec
{
[[GCDQueue backgroundPriorityGlobalQueue] execute:^{
block();
} afterDelay:NSEC_PER_SEC * sec];
}
+ (void)executeInMainQueue:(dispatch_block_t)block {
[[GCDQueue mainQueue] execute:^{
block();
}];
}
+ (void)executeInGlobalQueue:(dispatch_block_t)block {
[[GCDQueue globalQueue] execute:^{
block();
}];
}
+ (void)executeInHighPriorityGlobalQueue:(dispatch_block_t)block {
[[GCDQueue highPriorityGlobalQueue] execute:^{
block();
}];
}
+ (void)executeInLowPriorityGlobalQueue:(dispatch_block_t)block {
[[GCDQueue lowPriorityGlobalQueue] execute:^{
block();
}];
}
+ (void)executeInBackgroundPriorityGlobalQueue:(dispatch_block_t)block {
[[GCDQueue backgroundPriorityGlobalQueue] execute:^{
block();
}];
}
//3 GCDSemaphore 类
@interface GCDSemaphore : NSObject
@property (strong, readonly, nonatomic) dispatch_semaphore_t dispatchSemaphore;
#pragma 初始化以及释放
- (instancetype)init;
- (instancetype)initWithValue:(long)value;
#pragma 使用方法
- (BOOL)signal;
- (void)wait;
- (BOOL)wait:(int64_t)delta;
@end
#import "GCDSemaphore.h"
@interface GCDSemaphore ()
@property (strong, readwrite, nonatomic) dispatch_semaphore_t dispatchSemaphore;
@end
@implementation GCDSemaphore
- (instancetype)init {
self = [super init];
if (self) {
);
}
return self;
}
- (instancetype)initWithValue:(long)value {
self = [super init];
if (self) {
self.dispatchSemaphore = dispatch_semaphore_create(value);
}
return self;
}
- (BOOL)signal {
return dispatch_semaphore_signal(self.dispatchSemaphore)
!= ;
}
- (void)wait {
dispatch_semaphore_wait(self.dispatchSemaphore, DISPATCH_TIME_FOREVER);
}
- (BOOL)wait:(int64_t)delta {
return dispatch_semaphore_wait(self.dispatchSemaphore, dispatch_time(DISPATCH_TIME_NOW,
delta)) == ;
}
//4 GCDTimer
class GCDQueue;
@interface GCDTimer : NSObject
@property (strong, readonly, nonatomic) dispatch_source_t dispatchSource;
#pragma 初始化以及释放
- (instancetype)init;
- (instancetype)initInQueue:(GCDQueue *)queue;
#pragma 使用方法
- (void)event:(dispatch_block_t)block timeInterval:(uint64_t)interval;
- (void)start;
- (void)destroy;
@end
#import "GCDTimer.h"
#import "GCDQueue.h"
@interface GCDTimer ()
@property (strong, readwrite, nonatomic) dispatch_source_t dispatchSource;
@end
@implementation GCDTimer
- (instancetype)init
{
self = [super init];
if (self) {
self.dispatchSource = \
));
}
return self;
}
- (instancetype)initInQueue:(GCDQueue *)queue {
self = [super init];
if (self) {
self.dispatchSource = \
,
queue.dispatchQueue);
}
return self;
}
- (void)event:(dispatch_block_t)block timeInterval:(uint64_t)interval
{
dispatch_source_set_timer(self.dispatchSource,
),
interval,
);
dispatch_source_set_event_handler(self.dispatchSource,
^{
block();
});
}
- (void)start {
dispatch_resume(self.dispatchSource);
}
- (void)destroy {
dispatch_source_cancel(self.dispatchSource);
}
//GCD.h
#import "GCDQueue.h"
#import "GCDGroup.h"
#import "GCDSemaphore.h"
#import "GCDTimer.h"
GCD编程(封装GCD)的更多相关文章
- Object-C定时器,封装GCD定时器的必要性!!! (一)
实际项目开发中经常会遇到延迟某件任务的执行,或者让某件任务周期性的执行.然后也会在某些时候需要取消掉之前延迟执行的任务. iOS中延迟操作有三种解决方案: 1.NSObject的方法:(对象方法) p ...
- GCD编程 之 略微提高篇
额外任务:学习YouXianMing封装好的GCD源码 1.GCD串行队列与并发队列 串行队列一次只执行一个线程,按照添加到队列的顺序依次执行 并发队列一次可以执行多个线程,线程的执行没有先后 ...
- Object-C定时器,封装GCD定时器的必要性!!! (二)
上一篇:Object-C定时器,封装GCD定时器的必要性!!! (一) 上一篇认识了Object-C中的几种定时器,这一篇将Dispatch定时器(GCD定时器)封装起来. p.p1 { margin ...
- 欧几里得算法:从证明等式gcd(m, n) = gcd(n, m mod n)对每一对正整数m, n都成立说开去
写诗或者写程序的时候,我们经常要跟欧几里得算法打交道.然而有没要考虑到为什么欧几里得算法是有效且高效的,一些偏激(好吧,请允许我用这个带有浓重个人情感色彩的词汇)的计算机科学家认为,除非程序的正确性在 ...
- iOS边练边学--GCD的基本使用、GCD各种队列、GCD线程间通信、GCD常用函数、GCD迭代以及GCD队列组
一.GCD的基本使用 <1>GCD简介 什么是GCD 全称是Grand Central Dispatch,可译为“牛逼的中枢调度器” 纯C语言,提供了非常多强大的函数 GCD的优势 G ...
- python面向对象编程 -- 封装、继承
面向对象编程 -- 封装.继承 面向对象编程三要素:封装.继承和多态.本文主要看和封装.继承相关的概念:在python中多态的概念比较模糊,本文不做讨论. 1 封装 封装:将数据和操作组装到一起,对外 ...
- UVA 1642 Magical GCD(经典gcd)
题意:给你n(n<=100000)个正整数,求一个连续子序列使序列的所有元素的最大公约数与个数乘积最大 题解:我们知道一个原理就是对于n+1个数与n个数的最大公约数要么相等,要么减小并且减小至少 ...
- Solve Equation gcd(x,y)=gcd(x+y,lcm(x,y)) gcd(x,y)=1 => gcd(x*y,x+y)=1
/** 题目:Solve Equation 链接:http://acm.hnust.edu.cn/JudgeOnline/problem.php?id=1643 //最终来源neu oj 2014新生 ...
- 学习:数学----gcd及扩展gcd
gcd及扩展gcd可以用来求两个数的最大公因数,扩展gcd甚至可以用来求一次不定方程ax+by=c的解 辗转相除法与gcd 假设有两个数a与b,现在要求a与b的最大公因数,我们可以设 a=b*q+ ...
随机推荐
- debian 中的jdk
1 openjdk 2 debian安装java的脚本 3 下载bin自己编译
- BZOJ 4504: K个串
题目大意: 求一个序列的第k大的子串和. 题解: 对于一个右端点找最优的左端点,扔进堆里. 每次取堆顶,将这个右端点可以选择的左端点的区间分成两段,扔进堆里,重复k次. 现在需要对于一个固定的右端点, ...
- python基础学习笔记——初识函数
什么是函数 我们目前为止,已经可以完成一些软件的基本功能了,那么我们来完成这样一个功能:约x 1 2 3 4 5 pint("拿出手机") print("打开陌陌&quo ...
- [LoadRunner]LR性能测试结果样例分析
R性能测试结果样例分析 测试结果分析 LoadRunner性能测试结果分析是个复杂的过程,通常可以从结果摘要.并发数.平均事务响应时间.每秒点击数.业务成功率.系统资源.网页细分图.Web服务器资源. ...
- 【bzoj4804】欧拉心算 欧拉函数
题目描述 给出一个数字N 输入 第一行为一个正整数T,表示数据组数. 接下来T行为询问,每行包含一个正整数N. T<=5000,N<=10^7 输出 按读入顺序输出答案. 样例输入 1 1 ...
- java面试题之什么是死锁、活锁、饿死和竞态条件?
死锁:是指两个或两个以上的进程(或线程)在执行过程中,因争夺资源而造成的一种相互等待的现象,若无外力作用,他们将无法推进下去: 活锁:是指两个线程优先级相同,都礼让不走,就这样一直僵持下去: 饿死:在 ...
- spring中quartz的使用。【转http://www.cnblogs.com/kay/archive/2007/11/02/947372.html】
注:从spring3到spring4改变 org.springframework.scheduling.quartz.CronTriggerBean org.springframework.sched ...
- mysql解压之后的安装
远程连接报错(error:10061)看这篇:https://www.cnblogs.com/zipon/p/5877820.html 从5.6.20之后root会自动生成一个随机密码在/root/. ...
- The Closest M Points BZOJ 3053
The Closest M Points [问题描述] 软工学院的课程很讨厌!ZLC同志遇到了一个头疼的问题:在K维空间里面有许多的点,对于某些给定的点,ZLC需要找到和它最近的m个点. (这里的距离 ...
- Android网络编程之HttpClient运用
Android网络编程之HttpClient运用 在 Android开发中我们经常会用到网络连接功能与服务器进行数据的交互,为此Android的SDK提供了Apache的HttpClient来方便我们 ...