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"



基于iOS 使用GCD实现列表界面的图片异步下载

GCD 是Grand Central Dispatch 的简称,这是对多核编程的较新的解决方案,主要用于优化应用程序来支持多核处理器以及其他对称系统。     GCD提供了一种很简单的操作方式来实现并...
  • llyouss
  • llyouss
  • 2015年06月01日 16:10
  • 1332

GCD定时器的实现

http://www.jianshu.com/p/74a713cb5025 GCD定时器 GCD定时器不受RunLoop约束,比NSTimer更加准时 证明,实现GCD定时器...
  • jeffasd
  • jeffasd
  • 2016年05月20日 09:57
  • 362

iOS 用GCD下载网络图片方法

用多线程下载网络图片会导致重复下载浪费流量的问题。 以免出现以上情况,用多线程下载图片方法可以用以下方法。 1.创建一个字典,如果下载了该图片则将用图片地址为key,图片为value保存。 2....
  • zhangwenhai001
  • zhangwenhai001
  • 2015年08月08日 22:12
  • 1245

NSTimer、CADisplayLink、GCD 三种定时器的用法

在软件开发过程中,我们常常需要在某个时间后执行某个方法,或者是按照某个周期一直执行某个方法。在这个时候,我们就需要用到定时器。 在iOS中有很多方法完成定时器的任务,例如 NSTimer、CAD...
  • shan1991fei
  • shan1991fei
  • 2016年03月25日 09:33
  • 695

iOS GCD不同场景的使用比较

对比GCD不同情况的执行结果
  • feng2qing
  • feng2qing
  • 2016年03月24日 00:31
  • 1335

GCD高级用法-信号量

GCD中的信号量是指 Dispatch Semaphore。 所谓信号,类似于道路上的信号灯,一种用来标识等待还是通过的标志。绿灯通过,红灯等待。道路中通过信号灯的颜色标识通过和等待,而Dispat...
  • u014205965
  • u014205965
  • 2015年05月22日 11:25
  • 2276

多线程、特别是NSOperation 和 GCD 的内部原理

多线程、特别是NSOperation 和 GCD 的内部原理 简介 多线程是一个比较轻量级的方法来实现单个应用程序内多个代码执行路径。 在系统级别内,程序并排执行,程序分配到每个程序的执行时间是...
  • Charles91
  • Charles91
  • 2016年01月19日 15:44
  • 5777

iOS- NSThread/NSOperation/GCD 三种多线程技术的对比及实现

转自出处:http://www.cnblogs.com/qingche/p/3496190.html
  • martin_liang
  • martin_liang
  • 2014年11月02日 18:19
  • 7368

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

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

IOS GCD的介绍及使用举例&GCD优先级改变、after、group、barrier、sync、apply、semaphore、once等操作方法

GCD编程 目录 一、
  • u011711753
  • u011711753
  • 2014年04月18日 16:50
  • 2854
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:GCD编程(封装GCD)
举报原因:
原因补充:

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