YYDispatchQueuePool 是 YYKit 中用來控控制全局線程數(shù)的組件;
用法有下面兩種:
// 1. 從全局的 queue pool 中獲取一個 queue
dispatch_queue_t queue = YYDispatchQueueGetForQOS(NSQualityOfServiceUtility);
// 2. 創(chuàng)建一個新的 serial queue pool
YYDispatchQueuePool *pool = [[YYDispatchQueuePool alloc] initWithName:@"file.read" queueCount:5 qos:NSQualityOfServiceBackground];
dispatch_queue_t queue = [pool queue];
NSQualityOfService是 iOS8.0 提供的描述優(yōu)先級的枚舉值, 主要有下面幾種:
NSQualityOfServiceUserInteractive
NSQualityOfServiceUserInitiated
NSQualityOfServiceUtility
NSQualityOfServiceBackground
NSQualityOfServiceDefault
用來替代 GCD 中的dispatch_queue_priority_t
NSQualityOfServiceUserInteractive:最高優(yōu)先級, 用于處理 UI 相關的任務
NSQualityOfServiceUserInitiated:次高優(yōu)先級, 用于執(zhí)行需要立即返回的任務
NSQualityOfServiceUtility:普通優(yōu)先級,主要用于不需要立即返回的任務
NSQualityOfServiceBackground:后臺優(yōu)先級,用于處理一些用戶不會感知的任務
NSQualityOfServiceDefault:默認優(yōu)先級,當沒有設置優(yōu)先級的時候,線程默認優(yōu)先級
dispatch_queue_t YYDispatchQueueGetForQOS(NSQualityOfService qos)函數(shù)接收一個NSQualityOfService參數(shù)同時返回一個隊列;
函數(shù)內部又調用了另外一個函數(shù)static dispatch_queue_t YYDispatchContextGetQueue(YYDispatchContext *context);
YYDispatchContext結構體如下:
typedef struct {
const char *name;
void **queues;
uint32_t queueCount;
int32_t counter;
} YYDispatchContext;
context的獲取通過static YYDispatchContext *YYDispatchContextGetForQOS(NSQualityOfService qos)函數(shù)返回, 通過判斷不同的qos參數(shù)創(chuàng)建不同優(yōu)先級的context對象, context對象的創(chuàng)建, 放在了
static YYDispatchContext *YYDispatchContextCreate(const char *name, uint32_t queueCount, NSQualityOfService qos);
函數(shù)中, 這也是整個庫的核心函數(shù), 接收3個參數(shù): 隊列名、可用核心數(shù)、優(yōu)先級.
...
if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {
dispatch_qos_class_t qosClass = NSQualityOfServiceToQOSClass(qos);
for (NSUInteger i = 0; i < queueCount; i++) {
dispatch_queue_attr_t attr = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, qosClass, 0);
dispatch_queue_t queue = dispatch_queue_create(name, attr);
context->queues[i] = (__bridge_retained void *)(queue);
}
} else {
long identifier = NSQualityOfServiceToDispatchPriority(qos);
for (NSUInteger i = 0; i < queueCount; i++) {
dispatch_queue_t queue = dispatch_queue_create(name, DISPATCH_QUEUE_SERIAL);
dispatch_set_target_queue(queue, dispatch_get_global_queue(identifier, 0));
context->queues[i] = (__bridge_retained void *)(queue);
}
}
...
這里對 iOS8.0系統(tǒng)之前和 iOS8.0以后進行了分別處理;
iOS8.0之前:
先調用dispatch_queue_create(name, DISPATCH_QUEUE_SERIAL);創(chuàng)建一個串行隊列, 再調用dispatch_set_target_queue(queue, dispatch_get_global_queue(identifier, 0));設置隊列的優(yōu)先級, identifier與qos的對應關系如下:
switch (qos) {
case NSQualityOfServiceUserInteractive: return DISPATCH_QUEUE_PRIORITY_HIGH;
case NSQualityOfServiceUserInitiated: return DISPATCH_QUEUE_PRIORITY_HIGH;
case NSQualityOfServiceUtility: return DISPATCH_QUEUE_PRIORITY_LOW;
case NSQualityOfServiceBackground: return DISPATCH_QUEUE_PRIORITY_BACKGROUND;
case NSQualityOfServiceDefault: return DISPATCH_QUEUE_PRIORITY_DEFAULT;
default: return DISPATCH_QUEUE_PRIORITY_DEFAULT;
}
iOS8.0之后:
直接通過dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, qosClass, 0);創(chuàng)建一個attr參數(shù), 再調用dispatch_queue_create(name, attr)創(chuàng)建隊列; qosClass與qos的對應關系如下:
switch (qos) {
case NSQualityOfServiceUserInteractive: return QOS_CLASS_USER_INTERACTIVE;
case NSQualityOfServiceUserInitiated: return QOS_CLASS_USER_INITIATED;
case NSQualityOfServiceUtility: return QOS_CLASS_UTILITY;
case NSQualityOfServiceBackground: return QOS_CLASS_BACKGROUND;
case NSQualityOfServiceDefault: return QOS_CLASS_DEFAULT;
default: return QOS_CLASS_UNSPECIFIED;
}
queues 創(chuàng)建完成以后, 再設置queueCount和name, 至此context對象創(chuàng)建完成.
回到YYDispatchContextGetQueue函數(shù):
static dispatch_queue_t YYDispatchContextGetQueue(YYDispatchContext *context) {
// 原子操作, 自增counter
uint32_t counter = (uint32_t)OSAtomicIncrement32(&context->counter);
// 每次輪詢獲取不同的隊列
void *queue = context->queues[counter % context->queueCount];
return (__bridge dispatch_queue_t)(queue);
}
簡單測試一張圖片的下載可以看出:

