GUPImage库的队列管理

来源:互联网 发布:原生js ajax请求 编辑:程序博客网 时间:2024/06/08 09:55

最近项目进度不是很紧张,开始研究GUPImage库的源码,发现GUPImage中的队列管理方式设计的很巧妙,值得学习和分享。
在GPUImageOutput.h这个文件,声明了5种不同类型的队列执行方法:

void runOnMainQueueWithoutDeadlocking(void (^block)(void));void runSynchronouslyOnVideoProcessingQueue(void (^block)(void));void runAsynchronouslyOnVideoProcessingQueue(void (^block)(void));void runSynchronouslyOnContextQueue(GPUImageContext *context, void (^block)(void));void runAsynchronouslyOnContextQueue(GPUImageContext *context, void (^block)(void));

从这些方法的名字我们就能知道:
方法1:主线程执行并且不死锁。
方法2:在VideoProcessQueue中同步执行。
方法3:在VideoProcessQueue中异步执行。
方法4:在指定的GPUImageContext实例的VideoProcessingQueue中同步执行。
方法5:在指定的GPUImageContext实例的VideoProcessingQueue中异步执行。

如果这么说,你还是觉得很晕的话,下面我贴出起实现文件,一定会茅塞顿开。

void runOnMainQueueWithoutDeadlocking(void (^block)(void)){    if ([NSThread isMainThread])    {        block();    }    else    {        dispatch_sync(dispatch_get_main_queue(), block);    }}void runSynchronouslyOnVideoProcessingQueue(void (^block)(void)){    dispatch_queue_t videoProcessingQueue = [GPUImageContext sharedContextQueue];#if !OS_OBJECT_USE_OBJC#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wdeprecated-declarations"    if (dispatch_get_current_queue() == videoProcessingQueue)#pragma clang diagnostic pop#else    if (dispatch_get_specific([GPUImageContext contextKey]))#endif    {        block();    }else    {        dispatch_sync(videoProcessingQueue, block);    }}void runAsynchronouslyOnVideoProcessingQueue(void (^block)(void)){    dispatch_queue_t videoProcessingQueue = [GPUImageContext sharedContextQueue];#if !OS_OBJECT_USE_OBJC#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wdeprecated-declarations"    if (dispatch_get_current_queue() == videoProcessingQueue)#pragma clang diagnostic pop#else    if (dispatch_get_specific([GPUImageContext contextKey]))#endif    {        block();    }else    {        dispatch_async(videoProcessingQueue, block);    }}void runSynchronouslyOnContextQueue(GPUImageContext *context, void (^block)(void)){    dispatch_queue_t videoProcessingQueue = [context contextQueue];#if !OS_OBJECT_USE_OBJC#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wdeprecated-declarations"    if (dispatch_get_current_queue() == videoProcessingQueue)#pragma clang diagnostic pop#else        if (dispatch_get_specific([GPUImageContext contextKey]))#endif        {            block();        }else        {            dispatch_sync(videoProcessingQueue, block);        }}void runAsynchronouslyOnContextQueue(GPUImageContext *context, void (^block)(void)){    dispatch_queue_t videoProcessingQueue = [context contextQueue];#if !OS_OBJECT_USE_OBJC#pragma clang diagnostic push#pragma clang diagnostic ignored "-Wdeprecated-declarations"    if (dispatch_get_current_queue() == videoProcessingQueue)#pragma clang diagnostic pop#else        if (dispatch_get_specific([GPUImageContext contextKey]))#endif        {            block();        }else        {            dispatch_async(videoProcessingQueue, block);        }}

方法1:如果当前是运行在主线程,直接执行block。如果不是,则切换到主线程执行。
方法2:首先获取类的queue,然后同步执行。需要注意的是,类的queue是不能直接创建的,而是通过一个GPUImageContext的单例来维护的。很巧妙吧。
方法3:和方法2类似,只不过是异步执行的。
方法4:首先获取指定的GPUImageContext实例的queue,然后同步执行。
方法5:首先获取指定的GPUImageContext实例的queue,然后异步执行。

通过这些方法,就给GUPImage中的队列提供了一个统一的管理工具,减轻了队列管理的难度。

0 0
原创粉丝点击