Grand Central Dispatch(GCD)初探
来源:互联网 发布:js除以10000四舍五入 编辑:程序博客网 时间:2024/05/16 09:19
GCD提供和管理一些先进先出队列,你的应用程序可以以块的形式向这些队列提交任务。提交给队列的块在一个完全由系统维护的线程池上执行。线程对于运行在其上的任务并不作出任何保证。(No guarantee is made as to the thread on which a task executes.)
GCD 提供了三种队列:
主队列 Main: tasks execute serially on your application’s main thread// 任务按照次序在应用的主线程上执行
同步队列 Concurrent: tasks are dequeued in FIFO order, but run concurrently and can finish in any order.// 按先进先出次序出列,同步运行,但完成的次序是随即的。
串行队列 Serial: tasks execute one at a time in FIFO order// 按照先进先出的次序,每次执行一个任务
Calling
dispatch_main
Calling
UIApplicationMain
(iOS) orNSApplicationMain
(OS X)Using a
CFRunLoopRef
on the main thread
使用同步队列来同步执行大量的任务。GCD自动创建了三个同步队列,对应用来说,这三个队列是全局的,而且仅通过它们的优先级来区别。应用通过 dispatch_get_global_queue
函数请求那些队列。因为那些同步队列对于应用来说是全局的,你不需要保持或者释放它们,即使你这样做,也会被忽略掉。在OS X v10.7以上的系统中,你也可以创建额外的同部队列。在你的代码模块中使用。
使用串行队列要保证任务按照一定的顺序执行。为每个串行队列确定一个特定的目的是一个好的习惯,例如保护一个资源或者同步关键过程。应用必须明确地创建和管理串行队列。你可以按需创建串行队列,但是应该避免使用他们替代同步队列,同时执行大量任务。
重要提示:GCD是C语言的API,不处理高层次语言的任何异常,应用应该在提交给队列的块返回之前,处理所有异常。dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 异步操作 dispatch_async(dispatch_get_main_queue(), ^{ // UI更新 });});
dispatch_apply(num, globalQ, ^(size_t index) { // 执行num次,index为当前次数,从0开始计数});
-(void)LoadPage:(NSInteger)nPage :(NSInteger)num{ if (mIsLoading == YES) { return;// 正在加载中。。。。。。 } mIsLoading = YES; dispatch_queue_t displayQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(displayQueue, ^{ dispatch_apply(num, displayQueue, ^(size_t index){ // 执行num次 NSInteger curPage = nPage + index; //NSLog(@"%zu",index); NSLog(@"即将加载的页面为:%d",curPage); // 加载数据 sleep(2); // 更新页面 dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@" 更新页面%d",curPage); });// dispatch_get_main_queue });// dispatch_apply mIsLoading = NO;// 加载结束 });// dispatch_async}执行结果如下:
2、该思路使用一个串行队列来处理,具体如下:
if (mIsLoading == YES) { return;// 正在加载中。。。。。。 } mIsLoading = YES; dispatch_queue_t serialQueue = dispatch_queue_create("serialQueue", DISPATCH_QUEUE_SERIAL);//创建串行队列 dispatch_async(serialQueue, ^{ NSLog(@"加载页面 %d!",1); dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"更新UI 1!"); });// dispatch_get_main_queue });// dispatch_async 3 dispatch_async(serialQueue, ^{ NSLog(@"加载页面 %d!",2); dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"更新UI 2!"); });// dispatch_get_main_queue });// dispatch_async 3 dispatch_async(serialQueue, ^{ NSLog(@"加载页面 %d!",3); dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"更新UI 3!"); });// dispatch_get_main_queue });// dispatch_async 3 mIsLoading = NO;// 加载结束运行结果如下:
-(void)LoadPage:(NSInteger)nPage{ dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 异步操作 NSLog(@"即将加载的页面为:%d",nPage); // 加载数据 sleep(2); dispatch_async(dispatch_get_main_queue(), ^{ // UI更新 NSLog(@" 更新页面%d",nPage); }); });}调用的时候,使用循环传入须加载的页码的值。看似正确,实际有很大的安全问题。本质问题就在于,循环是在前台执行,而加载却在后台。
-(void)LoadPage:(NSInteger)nPage :(NSInteger)num for (int i = nPage; i< nPage+num; i++) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 异步操作 NSLog(@"即将加载的页面为:%d",i); // 加载数据 sleep(2); dispatch_async(dispatch_get_main_queue(), ^{ // UI更新 NSLog(@" 更新页面%d",i); }); }); }}这种方式跟上一种有异曲同工的错误,看看运行结果吧:
这明显是不正确的。
- Grand Central Dispatch(GCD)初探
- Grand Central Dispatch (GCD)
- GCD(Grand Central Dispatch)
- Grand Central Dispatch(GCD)
- Grand Central Dispatch (GCD
- Grand Central Dispatch (GCD)
- GCD(Grand Central Dispatch)
- GCD(Grand Central Dispatch)
- GCD(Grand Central Dispatch)
- GCD (Grand Central Dispatch)
- GCD(Grand Central Dispatch)
- Grand Central Dispatch(GCD)
- GCD (Grand Central Dispatch)
- GCD(Grand Central Dispatch)
- iOS Grand Central Dispatch(GCD)
- Grand Central Dispatch (GCD) Reference
- IOS GCD ---- Grand Central Dispatch
- GCD(Grand Central Dispatch)教程
- SDUT 1480 数据结构试验: 哈希表
- POJ 2002 Squares
- POJ 1442 Black Box
- POJ 2488 A Knight's Journey
- Java程序打包成jar包
- Grand Central Dispatch(GCD)初探
- POJ 2418 Hardwood Species
- POJ 1321 棋盘问题
- c++语法
- POJ 2251 Dungeon Master
- POJ 3126 Prime Path
- POJ 3087 Shuffle'm Up
- POJ 3414 Pots
- POJ 2676 sudoku