YYDispatchQueuePool阅读笔记

   阅读了开源大神的YYDispatchQueuePool,在此记下一些从中学到的东西。

   首先YYDispatchQueuePool.m文件中有如下类型对应:

static inline dispatch_queue_priority_t NSQualityOfServiceToDispatchPriority(NSQualityOfService 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;

    }

}

NSQualityOfService枚举定义了以下值:

  • UserInteractive:和图形处理相关的任务,比如滚动和动画。
  • UserInitiated:用户请求的任务,但是不需要精确到毫秒级。例如,如果用户请求打开电子邮件App来查看邮件。
  • Utility:周期性的用户请求任务。比如,电子邮件App可能被设置成每五分钟自动检查新邮件。但是在系统资源极度匮乏的时候,将这个周期性的任务推迟几分钟也没有大碍。
  • Background:后台任务,用户可能并不会察觉对这些任务。比如,电子邮件App对邮件进行引索以方便搜索。

而对于QOS YYDispatchQueuePool也有如下对应关系:

       1.  NSQualityOfServiceUserInteractive -> QOS_CLASS_USER_INTERACTIVE

       2.  NSQualityOfServiceUserInitiated -> QOS_CLASS_USER_INITIATED

       3.  NSQualityOfServiceUtility -> QOS_CLASS_USER_INITIATED

       4. NSQualityOfServiceBackground -> QOS_CLASS_BACKGROUND

       5. NSQualityOfServiceDefault -> QOS_CLASS_DEFAULT

我们可以看出在创建线程池的时候会与GCD里面的线程Dispatch Queue产生映射关系。

接下来他定义了这样一个结构体

typedef struct {

    const char *name;  // 定义一个name指针,用来储存队列名称

    void **queues;  //定义一个queues,指向队列的内存地址

    uint32_t queueCount; //队列个数

    int32_t counter;   //好吧,这里我也不是很清楚

} YYDispatchContext;

 

YYDispatchContextCreate (const char *name,  uint32_t queueCount,   NSQualityOfService qos);  //这里类似于C++里面的构造方法,也类似于OC里面的init方法,返回YYDispatchContext对象。

static YYDispatchContext *YYDispatchContextCreate(const char *name,
                                                 uint32_t queueCount,
                                                 NSQualityOfService qos) {
    YYDispatchContext *context = calloc(1, sizeof(YYDispatchContext));
    if (!context) return NULL;
    context->queues =  calloc(queueCount, sizeof(void *));
    if (!context->queues) {
        free(context);
        return NULL;
    }
    if ([UIDevice currentDevice].systemVersion.floatValue >= 8.0) {

    } 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);
        }
    }
    context->queueCount = queueCount;
    if (name) {
         context->name = strdup(name); //字符串拷贝函数
    }
    return context;
}

这里首先根据队列个数开辟相应个数的内存空间,然后再将QOS状态转换成队列优先级状态。前面已经列出了对应关系。根据初始化队列个数利用dispatch_queue_create(name,DISPATCH_QUEUE_SERIAL)生成对应的线程加到串行队列里面去。最后给YYDispatchContext的结构体赋值。同理,

YYDispatchContextRelease(YYDispatchContext *context)  //即为释放YYDispatchContext的方法,同样的我们来看一看源码

static void YYDispatchContextRelease(YYDispatchContext *context) {
    if (!context) return;
    if (context->queues) {
        for (NSUInteger i = 0; i < context->queueCount; i++) {
            void *queuePointer = context->queues[i];
            dispatch_queue_t queue = (__bridge_transfer dispatch_queue_t)(queuePointer);
            const char *name = dispatch_queue_get_label(queue);
            if (name) strlen(name);
            queue = nil;
        }
        free(context->queues);
        context->queues = NULL;
    }
    if (context->name) free((void *)context->name);
}

这里我们同样的遍历YYDispatchContext的队列,先是通过YYDispatchContext结构体的queues指针获取到dispatch_queue_t,然后对队列清空,最后利用C语言的free()函数释放内存空间。

  获取队列方法如下:

static dispatch_queue_t YYDispatchContextGetQueue(YYDispatchContext *context) {
    int32_t counter = OSAtomicIncrement32(&context->counter);
    if (counter < 0) counter = -counter;
    void *queue = context->queues[counter % context->queueCount];
    return (__bridge dispatch_queue_t)(queue);
}

之前讲到counter的时候不太理解这个的含义,这里代码主要是通过context获取队列。

接着

YYDispatchContext *YYDispatchContextGetForQOS(NSQualityOfService qos) ; //此方法是根据对应的qos状态创建YYDispatchContext;

最后使用起来也是比较方便,请参考YY大神的YYDispatchQueuePool

整个demo涵盖着对GCD的深入理解,C语言尤为重要



 

 

 

posted @ 2015-11-27 14:00  陈taotao  阅读(1023)  评论(0编辑  收藏  举报