码迷,mamicode.com
首页 > 其他好文 > 详细

GCD编程(封装GCD)

时间:2017-07-20 13:30:20      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:invoke   lock   track   nil   serial   object   tar   oss   cut   

//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编程(封装GCD)

标签:invoke   lock   track   nil   serial   object   tar   oss   cut   

原文地址:http://www.cnblogs.com/gavanwanggw/p/7210663.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!