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+ ...
随机推荐
- DSP中-stack和-heap的作用
-stack 0x00000800-heap 0x00000800 stack - 又称系统栈(system stack),用于: 保存函数调用后的返回地址; ...
- 俯瞰spring
[简化Java开发] 基于POJO的轻量级和最小入侵性编程: 通过依赖注入和面向接口实现松耦合: 基于切面和惯例进行声明式编程: 通过切面和模板减少样板代码: [容纳你的bean] 容器是spring ...
- PAT Basic 1053
1053 住房空置率 在不打扰居民的前提下,统计住房空置率的一种方法是根据每户用电量的连续变化规律进行判断.判断方法如下: 在观察期内,若存在超过一半的日子用电量低于某给定的阈值 e,则该住房为“可能 ...
- python基础——11(模块初识)
一.函数回调 # 提前写出函数的调用,再去考虑函数体的实现 # 怎么样提前写出函数的调用:在另一个函数中写出函数的调用 # 再去考虑函数体的实现:根据实际的需求 # 自定义一个sleep def my ...
- WPF IP地址输入控件的实现
一.前言 WPF没有内置IP地址输入控件,因此我们需要通过自己定义实现. 我们先看一下IP地址输入控件有什么特性: 输满三个数字焦点会往右移 键盘←→可以空光标移动 任意位置可复制整段IP地址,且支持 ...
- win10系统中virtualbox无法安装64位系统
win10系统中virtualbox无法安装64位系统 先总结下如果想在虚拟机中安装64位的Linux系统,最好能满足这几个条件: 64位CPU 64位操作系统 64位的虚拟机软件 开启BIOS虚拟化 ...
- angularJs模块ui-router之多视图
可以给ui-view指定名称,这样一个模板中就可以有多个ui-view.假设您有一个应用,需要动态填充graph.table data和filters,像下面这样: 当您需要使用多视图时,需要用到状态 ...
- Visual Studio 2013 滚动条实现代码缩略图
启动Visual studio 2013,打开工具->选项 在搜索选项输入,滚动条,英文版大概输入Scroll bar or Scroll 或者:文本编辑器->所有语言->滚动条 ...
- CSAPP学习笔记—虚拟内存
CSAPP学习笔记—虚拟内存 符号说明 虚拟内存地址寻址 图9-12展示了MMU如何利用页表来实现这种映射.CPU中的一个控制寄存器,页表基址寄存器(Page Table Base Register, ...
- 九度oj 题目1262:Sequence Construction puzzles(I)_构造全递增序列
题目描述: 给定一个整数序列,请问如何去掉最少的元素使得原序列变成一个全递增的序列. 输入: 输入的第一行包括一个整数N(1<=N<=10000). 接下来的一行是N个满足题目描述条件的整 ...