[翻译] GCDObjC
GCDObjC
https://github.com/mjmsmith/gcdobjc
GCDObjC is an Objective-C wrapper for the most commonly used features of Grand Central Dispatch. It has four main aims:
GCDObjC 封装了GCD最常使用的一些特性,它有着如下的4点宗旨:
- Organize the flat C API into appropriate classes.
- Use intention-revealing names to distinguish between synchronous and asynchronous functions.
- Use more convenient arguments such as time intervals.
- Add convenience methods.
- 将C语言级别的API转换成合适的对象类型
- 使用见名知意的名字来区分同步和异步的方法
- 用更便利的参数,如时间间隔
- 添加一些便利的方法
Usage(使用)
GCDObjC requires ARC and iOS 6.0. (Prior to 6.0, dispatch objects were not considered Objective-C objects, and therefore required manual memory management.)
GCDObjC.h is the only header file that needs to be imported.
GCDObjC需要开启ARC以及iOS6.0(在6.0之前,dispatch对象不被当做Objective-C对象,所以需要手动管理内存)
GCDObjC.h是唯一需要包含的头文件。
For usage examples, see GCDObjCTests.m.
GCDQueue(GCD队列)
Queues are implemented in the GCDQueue class.
在GCDQueue类中实现了队列。
- convenience accessors for global queues
- 便利的系统相关队列
+ (GCDQueue *)mainQueue;
+ (GCDQueue *)globalQueue;
+ (GCDQueue *)highPriorityGlobalQueue;
+ (GCDQueue *)lowPriorityGlobalQueue;
+ (GCDQueue *)backgroundPriorityGlobalQueue;
- creating serial and concurrent queues
- 创建串行以及并发队列
- (instancetype)initSerial;
- (instancetype)initConcurrent;
- queueing blocks for asynchronous execution
- 队列的block用来执行异步操作
- (void)queueBlock:(dispatch_block_t)block;
- (void)queueBlock:(dispatch_block_t)block afterDelay:(double)seconds;
- (void)queueBlock:(dispatch_block_t)block inGroup:(GCDGroup *)group;
- queueing blocks for synchronous execution
- 队列的block用来执行同步操作
- (void)queueAndAwaitBlock:(dispatch_block_t)block;
- (void)queueAndAwaitBlock:(void (^)(size_t))block iterationCount:(size_t)count;
- queueing barrier blocks for synchronous or asynchronous execution
- 队列阻塞block用来执行同步或者异步操作
- (void)queueBarrierBlock:(dispatch_block_t)block;
- (void)queueAndAwaitBarrierBlock:(dispatch_block_t)block;
- queueing notify blocks on groups
- 用来监测groups的队列
- (void)queueNotifyBlock:(dispatch_block_t)block inGroup:(GCDGroup *)group;
- suspending and resuming a queue
- 挂起以及回复一个队列
- (void)suspend;
- (void)resume;
GCDSemaphore(GCD信号量)
Semaphores are implemented in the GCDSemaphore class.
GCDSemaphore类实现了信号量
- creating semaphores
- 创建信号量
- (instancetype)init;
- (instancetype)initWithValue:(long)value;
- signaling and waiting on a semaphore
- 发送以及等待一个信号量
- (BOOL)signal;
- (void)wait;
- (BOOL)wait:(double)seconds;
GCDGroup(GCD线程组)
Groups are implemented in the GCDGroup class.
GCDGroup实现了线程组。
- creating groups
- 创建组
- (instancetype)init;
- entering and leaving a group
- 加入以及脱离一个组
- (void)enter;
- (void)leave;
- waiting on completion of a group
- 等待一个线程组执行完毕
- (void)wait;
- (BOOL)wait:(double)seconds;
Macros(宏函数)
Two macros are provided for wrapping dispatch_once() calls.
给dispatch_once()调用提供了两个宏。
- executing a block only once: GCDExecOnce(block)
- 仅仅执行一次
for (int i = 0; i < 10; ++i) {
GCDExecOnce(^{ NSLog(@"This will only be logged once."); });
}
- creating a singleton instance of a class: GCDSharedInstance(block)
- 创建一个类的单例
+ (instancetype)sharedInstance {
GCDSharedInstance(^{ return [[self class] new]; });
}
The block supplied to GCDSharedInstance() must return an instance of the desired class.
GCDShardInstance()必须返回这个类的一个实例对象。
------------------------------------------------------------------------------------------------------
此类仅仅支持arc,所以是在arc环境下测试,简单易用,以测了所有的情况
------------------------------------------------------------------------------------------------------
串行主线程池
[[GCDQueue mainQueue] queueBlock:^{ NSLog(@"1"); }]; [[GCDQueue mainQueue] queueBlock:^{ NSLog(@"2"); }]; [[GCDQueue mainQueue] queueBlock:^{ NSLog(@"3"); }]; [[GCDQueue mainQueue] queueBlock:^{ NSLog(@"4"); }];
2014-04-09 10:39:57.210 StudyGCD_new[10395:60b] 1
2014-04-09 10:39:57.210 StudyGCD_new[10395:60b] 2
2014-04-09 10:39:57.211 StudyGCD_new[10395:60b] 3
2014-04-09 10:39:57.211 StudyGCD_new[10395:60b] 4
串行主线程池与并发主线程池混用
[[GCDQueue globalQueue] queueBlock:^{ // 系统并发线程池 // ... 处理阻塞操作 [[GCDQueue mainQueue] queueBlock:^{ // 系统串行主线程池 // ... 更新UI操作 }]; }];
自己创建的并发线程池
GCDQueue *concurrentQueue = [[GCDQueue alloc] initConcurrent]; [concurrentQueue queueBlock:^{ NSLog(@"1"); }]; [concurrentQueue queueBlock:^{ NSLog(@"2"); }]; [concurrentQueue queueBlock:^{ NSLog(@"3"); }]; [concurrentQueue queueBlock:^{ NSLog(@"4"); }];
2014-04-09 11:08:39.450 StudyGCD_new[10592:1303] 1
2014-04-09 11:08:39.450 StudyGCD_new[10592:3903] 4
2014-04-09 11:08:39.450 StudyGCD_new[10592:3807] 2
2014-04-09 11:08:39.450 StudyGCD_new[10592:3707] 3
自己创建的串行线程池
GCDQueue *serialQueue = [[GCDQueue alloc] initSerial]; [serialQueue queueBlock:^{ NSLog(@"1"); }]; [serialQueue queueBlock:^{ NSLog(@"2"); }]; [serialQueue queueBlock:^{ NSLog(@"3"); }]; [serialQueue queueBlock:^{ NSLog(@"4"); }];
2014-04-09 11:08:39.450 StudyGCD_new[10592:1303] 1
2014-04-09 11:08:39.450 StudyGCD_new[10592:3903] 2
2014-04-09 11:08:39.450 StudyGCD_new[10592:3807] 3
2014-04-09 11:08:39.450 StudyGCD_new[10592:3707] 4
主并发线程池延时1s执行
NSLog(@"1"); [[GCDQueue globalQueue] queueBlock:^{ NSLog(@"Y.X."); } afterDelay:1.f]; NSLog(@"2");
2014-04-09 11:11:46.349 StudyGCD_new[10640:1303] 1
2014-04-09 11:11:46.350 StudyGCD_new[10640:1303] 2
2014-04-09 11:11:47.350 StudyGCD_new[10640:1303] Y.X.
并发线程池中运行阻塞线程(queueAndAwaitBlock-dispatch_sync)
GCDQueue *concurrentQueue = [[GCDQueue alloc] initConcurrent]; [concurrentQueue queueAndAwaitBlock:^{ sleep(1); NSLog(@"1"); }]; [concurrentQueue queueAndAwaitBlock:^{ sleep(1); NSLog(@"2"); }]; [concurrentQueue queueAndAwaitBlock:^{ sleep(1); NSLog(@"3"); }]; [concurrentQueue queueBlock:^{ NSLog(@"4"); }]; [concurrentQueue queueBlock:^{ NSLog(@"5"); }]; [concurrentQueue queueAndAwaitBlock:^{ sleep(1); NSLog(@"6"); }];
2014-04-09 11:21:15.186 StudyGCD_new[10946:60b] 1
2014-04-09 11:21:16.188 StudyGCD_new[10946:60b] 2
2014-04-09 11:21:17.190 StudyGCD_new[10946:60b] 3
2014-04-09 11:21:17.191 StudyGCD_new[10946:3807] 5
2014-04-09 11:21:17.191 StudyGCD_new[10946:1303] 4
2014-04-09 11:21:18.192 StudyGCD_new[10946:60b] 6
并发线程池,等待执行多次完毕后接着往下执行(dispatch_apply)
GCDQueue *concurrentQueue = [[GCDQueue alloc] initConcurrent]; NSLog(@"1-1-1"); [concurrentQueue queueAndAwaitBlock:^(size_t count) { NSLog(@"%zu", count); } iterationCount:4]; NSLog(@"2-2-2");
2014-04-09 11:27:39.400 StudyGCD_new[11131:60b] 1-1-1
2014-04-09 11:27:39.401 StudyGCD_new[11131:60b] 1
2014-04-09 11:27:39.401 StudyGCD_new[11131:1303] 0
2014-04-09 11:27:39.401 StudyGCD_new[11131:3707] 2
2014-04-09 11:27:39.401 StudyGCD_new[11131:3903] 3
2014-04-09 11:27:39.403 StudyGCD_new[11131:60b] 2-2-2
并发线程池,设置障碍线程而按照队列的形式执行(dispatch_barrier_async)
GCDQueue *concurrentQueue = [[GCDQueue alloc] initConcurrent]; [concurrentQueue queueBarrierBlock:^{ NSLog(@"1"); sleep(1); }]; [concurrentQueue queueBarrierBlock:^{ NSLog(@"2"); sleep(1); }]; [concurrentQueue queueBlock:^{ NSLog(@"Y.X."); sleep(1); }]; [concurrentQueue queueBarrierBlock:^{ NSLog(@"3"); sleep(1); }]; [concurrentQueue queueBarrierBlock:^{ NSLog(@"4"); sleep(1); }];
2014-04-09 11:33:08.190 StudyGCD_new[11252:1303] 1
2014-04-09 11:33:09.192 StudyGCD_new[11252:1303] 2
2014-04-09 11:33:10.194 StudyGCD_new[11252:1303] Y.X.
2014-04-09 11:33:11.196 StudyGCD_new[11252:1303] 3
2014-04-09 11:33:12.198 StudyGCD_new[11252:1303] 4
线程组以及监听
GCDQueue *concurrentQueue = [[GCDQueue alloc] initConcurrent]; GCDGroup *group = [[GCDGroup alloc] init]; [concurrentQueue queueBlock:^{ NSLog(@"1"); } inGroup:group]; [concurrentQueue queueBlock:^{ NSLog(@"2"); } inGroup:group]; [concurrentQueue queueBlock:^{ NSLog(@"3"); } inGroup:group]; [concurrentQueue queueNotifyBlock:^{ NSLog(@"监测所有这个组中的子线程完成后执行此打印语句"); } inGroup:group];
2014-04-09 11:37:19.492 StudyGCD_new[11343:3707] 3
2014-04-09 11:37:19.492 StudyGCD_new[11343:3807] 2
2014-04-09 11:37:19.492 StudyGCD_new[11343:1303] 1
2014-04-09 11:37:19.493 StudyGCD_new[11343:3807] 监测所有这个组中的子线程完成后执行此打印语句
先讲解系统的dispatch_group_enter来等待所有的异步操作结束后再执行最后的block
// 创建一个组 dispatch_group_t group = dispatch_group_create(); /* dispatch_group_enter() * A call to this function must be balanced with a call to dispatch_group_leave. * 调用了这个方法就必须使用dispatch_group_leave来达到平衡 */ // 明确的标记一个block进入了一个组 dispatch_group_enter(group); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ NSLog(@"1 starting"); sleep(1); NSLog(@"1 complete"); // 明确的标记一个这个组中的block已经完成 dispatch_group_leave(group); }); // 明确的标记一个block进入了一个组 dispatch_group_enter(group); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ NSLog(@"2 starting"); sleep(4); NSLog(@"2 complete"); // 明确的标记一个这个组中的block已经完成 dispatch_group_leave(group); }); dispatch_async(dispatch_get_main_queue(), ^{ // 同步等待之前提交的block任务都完成了才会执行这里 dispatch_group_wait(group, DISPATCH_TIME_FOREVER); NSLog(@"所有的进入group的都结束了,结束"); });
2014-04-09 13:10:32.518 StudyGCD_new[11864:1303] 1 starting
2014-04-09 13:10:32.518 StudyGCD_new[11864:3403] 2 starting
2014-04-09 13:10:33.520 StudyGCD_new[11864:1303] 1 complete
2014-04-09 13:10:36.521 StudyGCD_new[11864:3403] 2 complete
2014-04-09 13:10:36.522 StudyGCD_new[11864:60b] 所有的进入group的都结束了,结束
GCDGroup同步并发线程,更精简
GCDGroup *group = [[GCDGroup alloc] init]; [group enter]; [[GCDQueue globalQueue] queueBlock:^{ sleep(2); NSLog(@"1结束"); [group leave]; }]; [group enter]; [[GCDQueue globalQueue] queueBlock:^{ sleep(3); NSLog(@"2结束"); [group leave]; }]; [[GCDQueue globalQueue] queueBlock:^{ [group wait]; NSLog(@"1.2都执行结束了,进来了这里"); }];
2014-04-09 13:16:17.584 StudyGCD_new[11945:1303] 1结束
2014-04-09 13:16:18.584 StudyGCD_new[11945:3807] 2结束
2014-04-09 13:16:18.585 StudyGCD_new[11945:3707] 1.2都执行结束了,进来了这里
使用系统的信号量操作
// 创建信号量 dispatch_semaphore_t sem = dispatch_semaphore_create(0); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { NSLog(@"1开始"); // 模拟阻塞操作 sleep(2); NSLog(@"1结束"); // 增加信号量 dispatch_semaphore_signal(sem); sleep(1); dispatch_semaphore_signal(sem); sleep(1); dispatch_semaphore_signal(sem); sleep(1); dispatch_semaphore_signal(sem); }); NSLog(@"阻塞吗?"); // 减少信号量 dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); NSLog(@"阻塞了1!"); // 减少信号量 dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); NSLog(@"阻塞了2!"); // 减少信号量 dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); NSLog(@"阻塞了3!"); // 减少信号量 dispatch_semaphore_wait(sem, DISPATCH_TIME_FOREVER); NSLog(@"阻塞了4!");
2014-04-09 13:31:10.135 StudyGCD_new[12198:1303] 1开始
2014-04-09 13:31:10.134 StudyGCD_new[12198:60b] 阻塞吗?
2014-04-09 13:31:12.137 StudyGCD_new[12198:1303] 1结束
2014-04-09 13:31:12.138 StudyGCD_new[12198:60b] 阻塞了1!
2014-04-09 13:31:13.139 StudyGCD_new[12198:60b] 阻塞了2!
2014-04-09 13:31:14.140 StudyGCD_new[12198:60b] 阻塞了3!
2014-04-09 13:31:15.141 StudyGCD_new[12198:60b] 阻塞了4!
信号量操作
GCDSemaphore *semaphore = [[GCDSemaphore alloc] initWithValue:0]; [[GCDQueue globalQueue] queueBlock:^{ sleep(4); [semaphore signal]; }]; [semaphore wait]; NSLog(@"结束");
2014-04-09 13:39:09.476 StudyGCD_new[12298:60b] 结束