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,
\

dispatch_time(DISPATCH_TIME_NOW, delta)) == 0;

}

@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 = \

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

highPriorityGlobalQueue = [GCDQueue new];

highPriorityGlobalQueue.dispatchQueue = \

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);

lowPriorityGlobalQueue = [GCDQueue new];

lowPriorityGlobalQueue.dispatchQueue = \

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);

backgroundPriorityGlobalQueue = [GCDQueue new];

backgroundPriorityGlobalQueue.dispatchQueue = \

dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);

}

}

- (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) {

self.dispatchSemaphore = dispatch_semaphore_create(0);

}

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)
!= 0;

}

- (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)) == 0;

}

//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 = \

dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));

}

return self;

}

- (instancetype)initInQueue:(GCDQueue *)queue {

self = [super init];

if (self) {

self.dispatchSource = \

dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,
queue.dispatchQueue);

}

return self;

}

- (void)event:(dispatch_block_t)block timeInterval:(uint64_t)interval
{

dispatch_source_set_timer(self.dispatchSource,

dispatch_time(DISPATCH_TIME_NOW, 0),

interval,

0);

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"

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-07-30 20:26:45

GCD编程(封装GCD)的相关文章

多线程编程4 - GCD

一.简介 在iOS所有实现多线程的方案中,GCD应该是最有魅力的,因为GCD本身是苹果公司为多核的并行运算提出的解决方案.GCD在工作时会自动利用更多的处理器核心,以充分利用更强大的机器.GCD是Grand Central Dispatch的简称,它是基于C语言的.如果使用GCD,完全由系统管理线程,我们不需要编写线程代码.只需定义想要执行的任务,然后添加到适当的调度队列(dispatch queue).GCD会负责创建线程和调度你的任务,系统直接提供线程管理 二.调度队列(dispath qu

gcd的封装(swift)

gcd的封装(swift) by 伍雪颖 override func viewDidLoad() { delay(2) { println("2s later") } let task = delay(5) { println("call") } cancel(task) } typealias Task = (cancel : Bool) -> () func delay(time:NSTimeInterval,task:()->()) -> T

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新生选拔赛题 题意:给定两个数的和以及他们的最小公倍数,求这两个数. 思路: x+y=A lcm(x,y)=B => x*y/gcd(x,y)=B 要把这两个公式联立,那么必须消掉gcd: 设:d = gcd(x,y), x = kx*d, y = ky*d; kx与ky互质: x+y=A => d(

Python面向对象编程-封装

1引言 你点击了桌面上的Chrome图标,一个浏览器窗口出现了,输入网址就可以在Internet世界愉快玩耍.这一切是怎么实现的呢?Chromium这个多进程的程序是如何启动各个进程的呢?浏览器主进程(界面进程)启动了哪些线程?如何启动的呢?这些问题一直萦绕在心头,一起来看看源代码吧.本文主要针对Chromium for Mac的源代码,其它操作系统大同小异. 2背景知识 浏览器作为一个应用程序,是以进程的形式运行在操作系统上的.首先,Chromium是一个多进程的应用程序,我们需要了解Chro

UVA 1642 Magical GCD(经典gcd)

题意:给你n(n<=100000)个正整数,求一个连续子序列使序列的所有元素的最大公约数与个数乘积最大 题解:我们知道一个原理就是对于n+1个数与n个数的最大公约数要么相等,要么减小并且减小至少一半(至少少了一个因子) 因此所有子串gcd的总种类数最多只有n*log(a(数字大小))个 我们枚举每个点计算以这个点为结束点的所有后缀,利用dp的思想通过前一次计算的最多log(a)个gcd计算出此时也是最多log(a')个gcd import java.util.Scanner; public cl

欧几里得算法:从证明等式gcd(m, n) = gcd(n, m mod n)对每一对正整数m, n都成立说开去

写诗或者写程序的时候,我们经常要跟欧几里得算法打交道.然而有没要考虑到为什么欧几里得算法是有效且高效的,一些偏激(好吧,请允许我用这个带有浓重个人情感色彩的词汇)的计算机科学家认为,除非程序的正确性在数学上得到了完全严格的证实,否则我们不能认为程序是正确的.既然存在即合理,因此下面我就详细得解说一下欧几里得算法,它为什么是正确的算法(算法过程就不给出了,有了思想,无论是迭代还是循环实现应该都不成问题),为什么有那么好的时间复杂性. 首先还是证明上述命题:注意到证明了该命题就证明了欧几里得算法的正

Codeforces Round #554 (Div. 2) C. Neko does Maths (数论 GCD(a,b) = GCD(a,b-a))

传送门 •题意 给出两个正整数 a,b: 求解 k ,使得 LCM(a+k,b+k) 最小,如果有多个 k 使得 LCM() 最小,输出最小的k: •思路 时隔很久,又重新做这个题 温故果然可以知新? 重要知识点 GCD(a,b)=GCD(a,b-a)=GCD(b,b-a) (b>a) 证明: 设GCD(a,b)=c 则a%c=0,b%c=0,(b-a)%c=0 所以GCD(a,b-a)=c 得GCD(a,b)=GCD(a,b-a) gcd(a+k,b-a)肯定是(b-a)的因子 所以gcd(a

GCD编程-串行队列与并发队列

接着上面的GCD封装,以下进行列子验证 1.导入GCD.h 2.创一个串行队列: - (void)serailQueue{ //创建出队列 GCDQueue *queue =  [[GCDQueue alloc]initSerial]; //运行队列中的线程 [queue execute:^{ NSLog(@"1"); }]; [queue execute:^{ NSLog(@"2"); }]; [queue execute:^{ NSLog(@"3&qu

iOS 并行编程:GCD Dispatch Queues

1 简介 1.1 功能       Grand Central Dispatch(GCD)技术让任务并行排队执行,根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务.任务可以是一个函数(function)或者是一个block. GCD的底层依然是用线程实现,不过这样可以让程序员不用关注实现的细节. GCD中的队列称为dispatch queue,它可以保证先进来的任务先得到执行通过它能够大大简化多线程编程.工程师只要将要执行的任务(执行代码块)放入队列中,GCD将会为需要执行的任务创建