学习GCD后感——转自海森v

来源:互联网 发布:squid linux 下载 编辑:程序博客网 时间:2024/04/30 19:38

学习iOS到今天有3个月,也要准备面试,总是碰到gcd的问题,今天翻看了一下gcd的资料,整理一下。如果您是大牛,看到笑完之后请赐教,菜鸟一起学习。

(1)GCD是什么

Grand Central Dispatch(宏伟的派件中心 直译个人叫法,非官方):系统管理线程,你不需要编写线程代码。只需要定义想要执行的任务然后添加到适当的dispath queue.GCD会负责创建线程和调度你的任务。系统直接提供线程管理,比应用实现更加高效。

(2)GCD dispatch queues(派遣队列-个人叫法) 是执行任务的强大工具,允许你同步或异步地执行任意代码block。原先使用单独线程执行的所有任务都可以替换为使用dispatch quues。而dispatch queues最大的优点在于使用简单而且更加高效。

dispatch queue 是类似于对象的结构体,管理你提交给它的任务,而且都是先进先出(FIFO)的数据结构。因此queue中的任务总是以添加的顺序开始执行。GCD提供了几种dispatch queues 。不过你也自己创建。

三种queues:

串行Dispatch Queue:(待补充说明)

全局并发Dispatch Queue:(待补充说明)

main dispatch queue;(待补充说明)

(3)GCD 和线程相比的优点?

应用使用dispatch queue,相比线程有很多优点,最直接的优点是简单,不用编写线程创建和管理的代码,让你集中精力编写实际工作的代码。另外系统管理线程更加高效,并且可以动态调控所有线程。

dispatch queues 比线程具有更强的可预测性,例如两个线程访问共享资源,你可能无法控制哪个线程先后访问;但是把两个任务添加到串行queue,则可以确保两个任务对共享资源的饿访问顺序。同时基于queue的同步也比基于锁的线程同步机制更加高效。

(4)如何获得三种队列?

获得全局并发Dispatch Queue:

系统给每个应用提供三个并发dispatch queue ,所有应用全局共享,三个queue的区别是优先级。你不需要显示的创建这些queue,使用dispatch_get_global_queue 函数来获取这三个queue,代码

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:14px;"><span style="font-size:18px;"> dispatch_queue_t firstGloabel = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);</span></span>  

第一个参数是优先级别,级别不同队列是不一样的,第二个参数flag作为保留字段备用(一般为0


创建串行Dispatch Queue :

 应用的任务需要按需要按特定顺序执行时,就需要使用串行Dispatch Queue ,串行queue每次只能执行一个任务。你可以使用串行queue来替代锁,保护共享资源或可变的数据结构。 

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:14px;"><span style="font-size:18px;">    dispatch_queue_t firstQueue = dispatch_queue_create("com.example.Haisheng"NULL);  
  2. </span></span>  
 dispatch_queue_create函数创建串行queue,两个参数分别是queue名和一组queue属性。

获得主队列:

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:14px;"><span style="font-size:18px;">    dispatch_queue_t mainQueue = dispatch_get_main_queue();  
  2. </span></span>  
(5)添加任务到Queue

要执行一个任务,你需要将它dispatch到一个适当的dispatch queue,你可以同步或异步地dispatch一个任务,也可以单个或按组来dispatch 。一旦进入到queue,queue会负责尽快地执行你的任务。

你可以异步或同步地添加一个任务到Queue,金可能地使用dispatch_async或dispatch_async_f函数异步地dispatch任务。

来点实际的

 // GCD 相关函数说明

 //    dispatch_get_main_queue();

//    dispatch_async 函数会将传入的block块放入指定的queue里运行。这个函数是异步的,这就意味着它会立即返回而不管block是否运行结束。因此,我们可以在block里运行各种耗时的操作(如网络请求)而同时不会阻塞UI线程。

//    dispatch_get_global_queue 会获取一个全局队列,我们姑且理解为系统为我们开启的一些全局线程。我们用priority指定队列的优先级,而flag作为保留字段备用(一般为0)。

//    dispatch_get_main_queue 会返回主队列,也就是UI队列。它一般用于在其它队列中异步完成了一些工作后,需要在UI队列中更新界面(比如上面代码中的[self updateUIWithResult:result])的情况。

最后上一个磊哥的例子:

[objc] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. <span style="font-size:14px;">//  
  2. //  RootViewController.m  
  3. //  GCD  
  4. //  
  5. //  Created by on 14-9-1.  
  6. //  Copyright (c) 2014年  All rights reserved.  
  7. //  
  8.   
  9. #import "RootViewController.h"  
  10.   
  11. @interface RootViewController ()  
  12.   
  13. @end  
  14.   
  15. @implementation RootViewController  
  16.   
  17. #define kImageString @"http://static.oschina.net/uploads/user/136/272738_50.jpg?t=1409534522000"  
  18.   
  19. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  20. {  
  21.     self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  22.     if (self) {  
  23.         // Custom initialization  
  24.     }  
  25.     return self;  
  26. }  
  27.   
  28. - (void)viewDidLoad  
  29. {  
  30.     [super viewDidLoad];  
  31.     UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];  
  32.     [btn setTitle:@"gcd" forState:UIControlStateNormal];  
  33.     [btn setFrame:CGRectMake(10,30,300,50)];  
  34.     [btn addTarget:self action:@selector(btnClicked:) forControlEvents:UIControlEventTouchUpInside];  
  35.     [self.view addSubview:btn];  
  36. }  
  37.   
  38. /*1、GCD 是苹果iOS4.0之后和block一起出现的技术,是苹果封装的更底层(c)更高效的多线程处理技术 
  39.  *2、GCD (grand-central-dispatch)是目前使用的最普遍的多线程处理技术,因为高效、简洁、实用 
  40.  */  
  41. - (void)btnClicked:(UIButton *)btn{  
  42.  //gcd 中有一个主队列来管理和调度主线程  
  43.  //有三个优先级的全局队列用于管理和调度子线程  
  44.  //通过优先级为default的全局队列,在主线程之外,开辟的一个子线程  
  45.    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  46.        //此block 为子线程对应的函数  
  47.        NSURL *url = [NSURL URLWithString:kImageString];  
  48.        NSData *data = [NSData dataWithContentsOfURL:url];  
  49.        UIImage *image = [UIImage imageWithData:data];  
  50.        if (image) {  
  51.           //回到主线程,执行后续的操作  
  52.            //通过主队列回到主线程  
  53.            dispatch_async(dispatch_get_main_queue(), ^{  
  54.                //此block中的代码 在主线程中执行  
  55.                self.view.backgroundColor = [UIColor colorWithPatternImage:image];  
  56.            });  
  57.        }  
  58.    });  
  59. }  
  60.   
  61. - (void)didReceiveMemoryWarning  
  62. {  
  63.     [super didReceiveMemoryWarning];  
  64.     // Dispose of any resources that can be recreated.  
  65. }  
  66.   
  67.   
  68.   
  69.   
  70.   
  71.   
  72.   
  73.   
  74.   
  75.   
  76.   
  77. @end  
  78. </span>  
0 0
原创粉丝点击