GCD编程(封装GCD)

原创 2015年07月11日 10:27:40

//GCDGroup 类

@interface GCDGroup : NSObject

@property (strongnonatomicreadonlydispatch_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 (strongnonatomicreadwritedispatch_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.dispatchGroupDISPATCH_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 (strongreadonlynonatomicdispatch_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 (strongreadwritenonatomicdispatch_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_DEFAULT0);

        

        highPriorityGlobalQueue = [GCDQueue new];

        highPriorityGlobalQueue.dispatchQueue = \

        dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH0);

        

        lowPriorityGlobalQueue = [GCDQueue new];

        lowPriorityGlobalQueue.dispatchQueue = \

        dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW0);

        

        backgroundPriorityGlobalQueue = [GCDQueue new];

        backgroundPriorityGlobalQueue.dispatchQueue = \

        dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND0);

    }

}


- (instancetype)init {

    return [self initSerial];

}


- (instancetype)initSerial {

    self = [super init];

    if (self)

    {

        self.dispatchQueue = dispatch_queue_create(nilDISPATCH_QUEUE_SERIAL);

    }

    return self;

}


- (instancetype)initConcurrent {

    self = [super init];

    if (self)

    {

        self.dispatchQueue = dispatch_queue_create(nilDISPATCH_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.dispatchGroupself.dispatchQueue, block);

}


- (void)notify:(dispatch_block_t)block inGroup:(GCDGroup *)group {

    dispatch_group_notify(group.dispatchGroupself.dispatchQueue, block);

}



#pragma mark - 便利的构造方法

+ (void)executeInMainQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec {

    [[GCDQueue mainQueueexecute:^{

        block();

    } afterDelay:NSEC_PER_SEC * sec];

}


+ (void)executeInGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec {

    [[GCDQueue globalQueueexecute:^{

        block();

    } afterDelay:NSEC_PER_SEC * sec];

}


+ (void)executeInHighPriorityGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec {

    [[GCDQueue highPriorityGlobalQueueexecute:^{

        block();

    } afterDelay:NSEC_PER_SEC * sec];

}


+ (void)executeInLowPriorityGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec {

    [[GCDQueue lowPriorityGlobalQueueexecute:^{

        block();

    } afterDelay:NSEC_PER_SEC * sec];

}


+ (void)executeInBackgroundPriorityGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec {

    [[GCDQueue backgroundPriorityGlobalQueueexecute:^{

        block();

    } afterDelay:NSEC_PER_SEC * sec];

}


+ (void)executeInMainQueue:(dispatch_block_t)block {

    [[GCDQueue mainQueueexecute:^{

        block();

    }];

}


+ (void)executeInGlobalQueue:(dispatch_block_t)block {

    [[GCDQueue globalQueueexecute:^{

        block();

    }];

}


+ (void)executeInHighPriorityGlobalQueue:(dispatch_block_t)block {

    [[GCDQueue highPriorityGlobalQueueexecute:^{

        block();

    }];

}


+ (void)executeInLowPriorityGlobalQueue:(dispatch_block_t)block {

    [[GCDQueue lowPriorityGlobalQueueexecute:^{

        block();

    }];

}


+ (void)executeInBackgroundPriorityGlobalQueue:(dispatch_block_t)block {

    [[GCDQueue backgroundPriorityGlobalQueueexecute:^{

        block();

    }];

}


//3 GCDSemaphore 类


@interface GCDSemaphore : NSObject


@property (strongreadonlynonatomicdispatch_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 (strongreadwritenonatomicdispatch_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.dispatchSemaphoreDISPATCH_TIME_FOREVER);

}


- (BOOL)wait:(int64_t)delta {

    return dispatch_semaphore_wait(self.dispatchSemaphoredispatch_time(DISPATCH_TIME_NOW, delta)) == 0;

}


//4 GCDTimer

class GCDQueue;


@interface GCDTimer : NSObject


@property (strongreadonlynonatomicdispatch_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 (strongreadwritenonatomicdispatch_source_t dispatchSource;

@end


@implementation GCDTimer


- (instancetype)init

{

    self = [super init];

    if (self) {

        self.dispatchSource = \

        dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER00dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT0));

    }

    return self;

}


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

    self = [super init];

    if (self) {

        self.dispatchSource = \

        dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER00, queue.dispatchQueue);

    }

    return self;

}


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

    dispatch_source_set_timer(self.dispatchSource,

                              dispatch_time(DISPATCH_TIME_NOW0),

                              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"



相关文章推荐

封装一个GCD定时器,彻底解决定时器循环引用、释放时机问题

相信大家在开发中都会使用到定时器, 但又常常对定时器的循环引用问题, NSTimer 释放时机的选择上,劳神费力! 读了本文,这些再也不是问题! 关于 NSTimer 创建定时器的方法,我就不多做描...
  • zxw_xzr
  • zxw_xzr
  • 2017年03月29日 18:50
  • 1375

IOS GCD Timer

GCD中的Timer GCD中的Timer应该是最灵活的,而且是多线程的。GCD中的Timer是靠Dispatch Source来实现的。 因此先需要声明一个dispatch_source_t本地...

二次封装的GCD使用

串行队列 & 并发队列  //创建队列   GCDQueue *queue = [[GCDQueue alloc] initConcurrent];   //initSerial  串行队列  ...
  • WiKi_Su
  • WiKi_Su
  • 2015年12月03日 10:08
  • 287

使用XIB自定义一个UIView,然后将这个view添加到controller的view 上(相当于所有界面都通过xib来实现)

一、新建一个single view application类型的iOS application工程,名字取为CustomView,如下图,我们不往CustomViewViewController.xi...

对 Xcode 菜单选项的详细探索

转自:http://blog.163.com/ygb_wmj/blog/static/21506504120151144585823/ Xcode - Menu  Fi...

GCD编程逻辑

  • 2014年09月23日 10:48
  • 193KB
  • 下载

iOS-多线程编程学习之GCD——串行队列和并发队列(五)

Grand Central Dispatch(GCD)有很多部分构成,例如有很好的语言特性,运行库,还提供了系统的、高效的方式来支持具有多核处理器的iOS和OS X设备进行并发事件处理。   BSD...

并发编程之Operation Queue和GCD

  • 2013年12月20日 10:28
  • 66KB
  • 下载

iOS GCD多核编程

  • 2013年05月08日 19:46
  • 30KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:GCD编程(封装GCD)
举报原因:
原因补充:

(最多只允许输入30个字)