I named it MDispatchQueuePool
.
Really easy to use:
[MDispatchQueuePool.sharedPool asyncExecute:^{
// put your code here ...
}];
Here is MDispatchQueuePool.m
@interface MDispatchQueuePool () {
dispatch_queue_t _executionQueue;
dispatch_queue_t _waitingQueue;
dispatch_semaphore_t _maximumQueueSemaphore;
}
@end
@implementation MDispatchQueuePool
+ (instancetype)sharedPool {
static MDispatchQueuePool *pool = nil;
static dispatch_once_t onceToken = 0;
dispatch_once(&onceToken, ^{
pool = [[self alloc] init];
});
return pool;
}
- (instancetype)init {
if (self = [super init]) {
_executionQueue = dispatch_queue_create("queue.exec.MDispatchQueuePool", DISPATCH_QUEUE_CONCURRENT);
_waitingQueue = dispatch_queue_create("queue.wait.MDispatchQueuePool", DISPATCH_QUEUE_SERIAL);
dispatch_set_target_queue(_executionQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0));
dispatch_set_target_queue(_waitingQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
NSUInteger processorCount = MAX(NSProcessInfo.processInfo.processorCount, 2);
_maximumQueueSemaphore = dispatch_semaphore_create(processorCount);
}
return self;
}
- (void)asyncExecute:(dispatch_block_t)block {
if (!block) {
return;
}
dispatch_block_t blockCopy = [block copy];
dispatch_async(_waitingQueue, ^{
dispatch_semaphore_wait(self->_maximumQueueSemaphore, DISPATCH_TIME_FOREVER);
dispatch_async(self->_executionQueue, ^ {
blockCopy();
dispatch_semaphore_signal(self->_maximumQueueSemaphore);
});
});
}
@end