//
|
// GCDQueue.m
|
// GCD
|
//
|
// 用法
|
// http://www.cnblogs.com/YouXianMing/p/3659204.html
|
//
|
// Created by XianMingYou on 15/3/15.
|
// Copyright (c) 2015年 XianMingYou. All rights reserved.
|
//
|
|
#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];
|
globalQueue = [GCDQueue new];
|
highPriorityGlobalQueue = [GCDQueue new];
|
lowPriorityGlobalQueue = [GCDQueue new];
|
backgroundPriorityGlobalQueue = [GCDQueue new];
|
|
mainQueue.dispatchQueue = dispatch_get_main_queue();
|
globalQueue.dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
|
highPriorityGlobalQueue.dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
|
lowPriorityGlobalQueue.dispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0);
|
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)initSerialWithLabel:(NSString *)label {
|
|
self = [super init];
|
if (self)
|
{
|
self.dispatchQueue = dispatch_queue_create([label UTF8String], DISPATCH_QUEUE_SERIAL);
|
}
|
|
return self;
|
}
|
|
- (instancetype)initConcurrent {
|
|
self = [super init];
|
|
if (self) {
|
|
self.dispatchQueue = dispatch_queue_create(nil, DISPATCH_QUEUE_CONCURRENT);
|
}
|
|
return self;
|
}
|
|
- (instancetype)initConcurrentWithLabel:(NSString *)label {
|
self = [super init];
|
if (self)
|
{
|
self.dispatchQueue = dispatch_queue_create([label UTF8String], DISPATCH_QUEUE_CONCURRENT);
|
}
|
return self;
|
}
|
|
- (void)execute:(dispatch_block_t)block {
|
|
NSParameterAssert(block);
|
dispatch_async(self.dispatchQueue, block);
|
}
|
|
- (void)execute:(dispatch_block_t)block afterDelay:(int64_t)delta {
|
|
NSParameterAssert(block);
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delta), self.dispatchQueue, block);
|
}
|
|
- (void)execute:(dispatch_block_t)block afterDelaySecs:(float)delta {
|
|
NSParameterAssert(block);
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delta * NSEC_PER_SEC), self.dispatchQueue, block);
|
}
|
|
- (void)waitExecute:(dispatch_block_t)block {
|
|
/*
|
As an optimization, this function invokes the block on
|
the current thread when possible.
|
|
作为一个建议,这个方法尽量在当前线程池中调用.
|
*/
|
|
NSParameterAssert(block);
|
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操作
|
*/
|
|
NSParameterAssert(block);
|
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.
|
|
作为一个建议,这个方法尽量在当前线程池中调用.
|
*/
|
|
NSParameterAssert(block);
|
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 {
|
|
NSParameterAssert(block);
|
dispatch_group_async(group.dispatchGroup, self.dispatchQueue, block);
|
}
|
|
- (void)notify:(dispatch_block_t)block inGroup:(GCDGroup *)group {
|
|
NSParameterAssert(block);
|
dispatch_group_notify(group.dispatchGroup, self.dispatchQueue, block);
|
}
|
|
|
#pragma mark - 便利的构造方法
|
+ (void)executeInMainQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec {
|
|
NSParameterAssert(block);
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * sec), mainQueue.dispatchQueue, block);
|
}
|
|
+ (void)executeInGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec {
|
|
NSParameterAssert(block);
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * sec), globalQueue.dispatchQueue, block);
|
}
|
|
+ (void)executeInHighPriorityGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec {
|
|
NSParameterAssert(block);
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * sec), highPriorityGlobalQueue.dispatchQueue, block);
|
}
|
|
+ (void)executeInLowPriorityGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec {
|
|
NSParameterAssert(block);
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * sec), lowPriorityGlobalQueue.dispatchQueue, block);
|
}
|
|
+ (void)executeInBackgroundPriorityGlobalQueue:(dispatch_block_t)block afterDelaySecs:(NSTimeInterval)sec {
|
|
NSParameterAssert(block);
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC * sec), backgroundPriorityGlobalQueue.dispatchQueue, block);
|
}
|
|
+ (void)executeInMainQueue:(dispatch_block_t)block {
|
|
NSParameterAssert(block);
|
dispatch_async(mainQueue.dispatchQueue, block);
|
}
|
|
+ (void)executeInGlobalQueue:(dispatch_block_t)block {
|
|
NSParameterAssert(block);
|
dispatch_async(globalQueue.dispatchQueue, block);
|
}
|
|
+ (void)executeInHighPriorityGlobalQueue:(dispatch_block_t)block {
|
|
NSParameterAssert(block);
|
dispatch_async(highPriorityGlobalQueue.dispatchQueue, block);
|
}
|
|
+ (void)executeInLowPriorityGlobalQueue:(dispatch_block_t)block {
|
|
NSParameterAssert(block);
|
dispatch_async(lowPriorityGlobalQueue.dispatchQueue, block);
|
}
|
|
+ (void)executeInBackgroundPriorityGlobalQueue:(dispatch_block_t)block {
|
|
NSParameterAssert(block);
|
dispatch_async(backgroundPriorityGlobalQueue.dispatchQueue, block);
|
}
|
|
@end
|