神刀安全网

谈谈GCD

什么是GCD

略。

GCD简单入门

GCD队列

GCD队列分串行队列和并行队列。 可以简单的理解为同步和异步。

获取队列

MainDispatchQueue

dispatch_queue_t queue = dispatch_get_main_queue(); 

主串行队列,它会将任务插入主线程的RunLoop中执行,所以很明显是串行队列。

GlobalDispatchQueue

    /** 优先级         DISPATCH_QUEUE_PRIORITY_HIGH          DISPATCH_QUEUE_PRIORITY_DEFAULT 默认         DISPATCH_QUEUE_PRIORITY_LOW          DISPATCH_QUEUE_PRIORITY_BACKGROUND 后台     */     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 

全局并行队列。第一个参数传入优先级,第二个参数则是传一个预留值,一般传0就行了。

加入队列

加入同步队列

    dispatch_sync(queue, ^{         NSLog(@"任务一完成");     });     dispatch_sync(queue, ^{         NSLog(@"任务二完成");     }); 

这样输出的结果肯定是”任务一完成”,”任务二完成”。

加入异步队列

    dispatch_async(queue, ^{         NSLog(@"任务一完成");     });     dispatch_async(queue, ^{         NSLog(@"任务二完成");     }); 

这样输出的结果是不确定的,有可能任务一先完成,也可能任务二先完成。

任务组

创建一个任务组

dispatch_group_t group = dispatch_group_create(); 

同步任务组

    dispatch_group_t group = dispatch_group_create();     dispatch_group_enter(group);     [self syncGroupBlock:^(int num) {         sleep(num);         NSLog(@"任务一完成");     }];     dispatch_group_leave(group);          dispatch_group_enter(group);     [self syncGroupBlock:^(int num) {         sleep(num);         NSLog(@"任务二完成");     }];     dispatch_group_leave(group);          dispatch_group_enter(group);     [self syncGroupBlock:^(int num) {         sleep(num);         NSLog(@"任务三完成");     }];     dispatch_group_leave(group);          dispatch_group_notify(group, self.otherQueue, ^{         NSLog(@"完成");     }); 

里面的syncGroupBlock是我简单的创建的一个Block,用来传来一个值,然后sleep(num)。

这样输出的结果肯定是任务依次完成,然后再输出“完成”。

然后 dispatch_group_enter(group)dispatch_group_leave(group) 是采用计数机制的,每一个enter都要对应一个leave,手动控制每个任务的开始和结束。

再通过 dispatch_group_notify(dispatch_group_t group, dispatch_queue_t queue, ^(void)block) 来监听任务全部完成。

异步任务组

    dispatch_group_t group = dispatch_group_create();     dispatch_group_async(group, queue, ^{         NSLog(@"任务一完成");     });     dispatch_group_async(group, queue, ^{         NSLog(@"任务二完成");     });     dispatch_group_async(group, queue, ^{         NSLog(@"任务三完成");     });     dispatch_group_notify(group, queue, ^{         NSLog(@"完成");     }); 

和同步任务组不同之处只是不需要手动控制,完成所有任务的监听还是一样的。

创建队列

当然你也可以不使用系统提供的主串行队列和全局并行队列。

创建串行队列

 dispatch_queue_t mySerialDispatchQueue = dispatch_queue_create("wzx.gcd", DISPATCH_QUEUE_SERIAL); 

第一个参数是你为这个队列取的名字,第二参数则是队列类型。

创建并行队列

 dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create("wzx.gcd", DISPATCH_QUEUE_CONCURRENT); 

和创建串行队列一致。

更改队列优先级

手动创建的队列和默认优先级全局队列优先级等同,如果需要修改队列的优先级,需要:

   dispatch_queue_t myConcurrentDispatchQueue = dispatch_queue_create("wzx.gcd", DISPATCH_QUEUE_CONCURRENT);   dispatch_queue_t targetQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);   dispatch_set_target_queue(myConcurrentDispatchQueue, targetQueue); 

GCD应用复杂场景

异步任务一和异步任务二完成后,才进行异步任务三和异步任务四

    dispatch_queue_t concurrentQueue = dispatch_queue_create("my.concurrent.queue", DISPATCH_QUEUE_CONCURRENT);     dispatch_async(concurrentQueue, ^{        NSLog(@"任务一完成");     });          dispatch_async(concurrentQueue, ^{         NSLog(@"任务二完成");     });          dispatch_barrier_async(concurrentQueue, ^{         NSLog(@"任务一、二已完成");     });          dispatch_async(concurrentQueue, ^{         NSLog(@"任务三完成");     });          dispatch_async(concurrentQueue, ^{         NSLog(@"任务四完成");     });          dispatch_barrier_async(concurrentQueue, ^{         NSLog(@"完成");     });  

首先获取一个并行队列。

然后通过:

dispatch_barrier_async(dispatch_queue_t queue, dispatch_block_t block) 

这个api的用处:挡住它之后的任务,直至它之前的任务完成。

阻滞主线程,知道所有任务完成

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);     dispatch_group_t group = dispatch_group_create();          dispatch_group_async(group, queue, ^{         NSLog(@"任务一完成");     });          dispatch_group_async(group, queue, ^{         sleep(10);         NSLog(@"任务二完成");     });          dispatch_group_async(group, queue, ^{         NSLog(@"任务三完成");     });               if (dispatch_group_wait(group, DISPATCH_TIME_FOREVER) == 0) {         NSLog(@"已经全部执行完毕");     }     else {         NSLog(@"没有执行完毕");     } 

当遇到 dispatch_group_wait 时,主线程会被挂起,直到达到第二个时间参数。

DISPATCH_TIME_FOREVER 的意思是永远等待。

Demo

Github:WzxJiang

转载本站任何文章请注明:转载至神刀安全网,谢谢神刀安全网 » 谈谈GCD

分享到:更多 ()

评论 抢沙发

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址