ios学习:多线程二(GCD初步介绍)

xib文件就放了四个button和四个label

 1 //
 2 //  TWFXViewController.h
 3 //  Demo_GCD
 4 //
 5 //  Created by Lion User on 12-12-11.
 6 //  Copyright (c) 2012年 Lion User. All rights reserved.
 7 //
 8 
 9 #import <UIKit/UIKit.h>
10 
11 @interface TWFXViewController : UIViewController
12 
13 @property (retain, nonatomic) IBOutlet UILabel *outletLabel1;
14 @property (retain, nonatomic) IBOutlet UILabel *outletLabel2;
15 @property (retain, nonatomic) IBOutlet UILabel *outletLabel3;
16 @property (retain, nonatomic) IBOutlet UILabel *outletLabel4;
17 
18 - (IBAction)btnClick4:(UIButton *)sender;
19 - (IBAction)btnClick2:(UIButton *)sender;
20 - (IBAction)btnClick3:(UIButton *)sender;
21 - (IBAction)btnClick:(UIButton *)sender;
22 @end
  1 //
  2 //  TWFXViewController.m
  3 //  Demo_GCD
  4 //
  5 //  Created by Lion User on 12-12-11.
  6 //  Copyright (c) 2012年 Lion User. All rights reserved.
  7 //
  8 /*
  9  GCD(系统管理线程) 简介
 10  使用GCD你不需要编写线程代码,只需定义想要执行的任务,然后添加到适当的 dispatch queue (调度队列)里
 11  GCD会负责创建线程和调度你的任务.系统直接提供线程管理,比应用实现更高效
 12  
 13  基于C的执行自定义任务机制,dispatch queue 按先进先出的顺序,串行或并发地执行任务.dispatch queue 分以下三种:
 14  serial dispatch queue : 串行调度队列,一次只执行一个任务,直到当前任务完成才开始出列并启动下一个任务
 15                          主要用于对特定资源的同步访问.虽然每个串行queue本身每次只能执行一个任务,但各个串行queue之间是并发执行的
 16  concurrent dispatch queue: 也称为 global dispatch queue, 并行调度队列,并发执行一个或多个任务,但启动顺序仍是按照添加到queue的顺序启动
 17                             你不能创建并发dispatch queues, 只能使用系统已经定义好了的三个全局并发queues,具体下面说到
 18  main dispatch queue : 全局可用的串行 queue,在应用主线程中执行任务,比如用于刷新UI界面
 19  
 20  
 21  dispatch queue 相关的技术
 22  Dispatch group : 用于监控一组block对象完成
 23  Dispatch semaphore : 类似于传统的 semaphore (信号量)
 24  Dispatch Source : 系统事件异步处理机制
 25  
 26  dispatch queue 中的 各个线程,可以通过queue的context指针来共享数据
 27  
 28  */
 29 
 30 
 31 #import "TWFXViewController.h"
 32 
 33 @interface TWFXViewController ()
 34 
 35 @end
 36 
 37 @implementation TWFXViewController
 38 
 39 - (void)viewDidLoad
 40 {
 41     [super viewDidLoad];
 42     // Do any additional setup after loading the view, typically from a nib.
 43 }
 44 
 45 - (void)didReceiveMemoryWarning
 46 {
 47     [super didReceiveMemoryWarning];
 48     // Dispose of any resources that can be recreated.
 49 }
 50 
 51 
 52 /*
 53  全局并发 Dispatch queue
 54  1. 并发 dispatch queue 可以同时并发执行多个任务,不过并发 queue 仍然按照先进先出的顺序启动任务
 55  2. 并发 queue 同时执行的任务数量会根据应用和系统动态变化,各个因素如:可用核数量  其他进程正在执行的工作数量 其他串行dispatch queue 中的优先任务的数量等
 56  3. 系统会给每个应用程序提供三个并发 dispatch queue,全局共享,三个queue的唯一区别在于优先级不同 
 57  */
 58 - (IBAction)btnClick4:(UIButton *)sender {
 59     
 60     /*
 61      获取全局并发 dispatch queue : dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
 62      第一个参数表示 queue 的优先级,这里获取默认优先级的那个queue,也可以获取高/低优先级的那个,把 DEFAULT 换成 HIGH 或 LOW 就行了
 63      第二个参数表示 ?
 64      */
 65     dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
 66     
 67     
 68     //把一个block加入到全局并发调度队列里
 69     dispatch_async(aQueue, ^(void) {
 70                 
 71         for (int i = 0; i < 1000; i++) {
 72             
 73             //把block同步添加到主线程里,这样子,demo queue 就会暂停等这个block执行完成才继续执行
 74             dispatch_sync(dispatch_get_main_queue(), ^(void) {
 75                 
 76                 NSString *text = [NSString stringWithFormat:@"%d", i];
 77                 self.outletLabel3.text = text;
 78             });            
 79         }
 80         
 81     });
 82     
 83     
 84     //把另一个block加入到全局并发调度队列里.这个block和上面那个block会并发执行
 85     dispatch_async(aQueue, ^(void){
 86         
 87         for (int i = 0; i < 1000; i++) {
 88             
 89             //把block同步添加到主线程里,这样子,demo queue 就会暂停等这个block执行完成才继续执行
 90             dispatch_sync(dispatch_get_main_queue(), ^(void) {
 91                 
 92                 NSString *text = [NSString stringWithFormat:@"%d", i];
 93                 self.outletLabel4.text = text;
 94             });
 95         }
 96         
 97     });
 98     
 99 }
100 
101 
102 /*
103  串行 Dispatch queue
104  1. 串行 queue 每次只能执行一个任务,可以使用它来代替锁,保护共享资源或可变的数据结构,串行queue确保任务按可预测的顺序执行(这是比锁好的地方)
105  2. 必须显式创建和管理所有你使用的串行queue(数目任意)
106  */
107 - (IBAction)btnClick2:(UIButton *)sender {
108     
109     /*
110      使用 dispatch_queue_create() 方法来创建串行queue
111      第一个参数表示 queue 的名字, 第二个参数表示 queue 的一组属性(保留给将来使用)
112      */
113     dispatch_queue_t queue = dispatch_queue_create("demo queue", NULL);
114     
115     
116     /*
117      异步调度和同步调度
118      异步调度 dispatch_async : 把一个任务添加到某queue后就马上离开,而不管任务在那个queue里的执行状态
119      同步调度 dispatch_sync : 把一个任务添加到某queue后,等这个任务完成,调用线程才继续执行.尼玛,坑爹啊
120      
121      所以,异步调度和同步调度的区别不在于被添加的任务怎样执行,而在于调用线程是否等待任务执行完
122      */
123     
124     //把block异步添加到上面创建的名为 demo queue 的调度队列里
125     dispatch_async(queue, ^(void){
126         
127         for (int i = 0; i < 1000; i++) {
128 
129          //   sleep(1);
130           //  printf("a%d\t",i);
131             
132             //把block同步添加到主线程里,这样子,demo queue 就会暂停等这个block执行完成才继续执行
133             dispatch_sync(dispatch_get_main_queue(), ^(void) {
134 
135                 NSString *text = [NSString stringWithFormat:@"%d", i];
136                 self.outletLabel1.text = text;
137                // printf("b%d\n",i);
138             });
139             
140         }
141         
142     });
143     
144     
145     //因为 demo queue 是串行调度队列,所以等上面那个block执行完,下面这个block才会开始
146     dispatch_async(queue, ^(void){
147         
148         for (int i = 0; i < 1000; i++) {
149   
150             dispatch_sync(dispatch_get_main_queue(), ^(void) {
151                 
152                 self.outletLabel2.text = [NSString stringWithFormat:@"%d", i];
153                 
154             });
155         }
156         
157 
158     });
159     
160     
161     //xxxxx_create 的object对象要对应 xxxxx_release ?
162     dispatch_release(queue);
163 
164     //这个循环都会卡屏幕~~~
165 //    for (int i = 0; i < 100000; i++) {
166 //        self.outletLabel1.text = [NSString stringWithFormat:@"%d", i];
167 //        printf("%d\n", i);
168 //    }
169     
170 }
171 
172              
173 -(void)test:(NSString *)data
174 {
175     self.outletLabel1.text = data;
176 }
177 
178 
179 
180 /*
181  dispatch_group 可以把一组task放到一个group里,等group里的所有task都执行完后再继续运行
182  */
183 - (IBAction)btnClick3:(UIButton *)sender {
184     
185     //重置label2的text
186     self.outletLabel2.text = @"begin";
187     
188     //获取一个全局并发 调度队列
189     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
190 
191     //创建一个 dispatch group
192     dispatch_group_t group = dispatch_group_create();
193     
194     //定义 task1
195     dispatch_block_t task1 = ^(void){
196         
197         for (int i = 0; i < 300; i++) {
198             
199             dispatch_sync(dispatch_get_main_queue(), ^(void){
200                 
201                 self.outletLabel3.text = [NSString stringWithFormat:@"%d", i];
202             });
203         }
204 
205     };
206     
207     //定义task2
208     dispatch_block_t task2 = ^(void){
209         
210         for (int i = 0; i < 300; i++) {
211             
212             dispatch_sync(dispatch_get_main_queue(), ^(void){
213                 
214                 self.outletLabel4.text = [NSString stringWithFormat:@"%d", i];
215             });
216         }
217         
218     };
219     
220     //把task1关联到 queue 和group
221     dispatch_group_async(group, queue, task1);
222     
223     //把task2关联到 queue和group
224     dispatch_group_async(group, queue, task2);
225     
226     
227     //等group里的task都执行完后执行notify方法里的内容,相当于把wait方法及之后要执行的代码合到一起了
228     dispatch_group_notify(group, dispatch_get_main_queue(), ^(void){
229         
230         self.outletLabel2.text = @"done!";
231         
232     });
233     
234     //XXX_create创建,就需要对应的 XXX_release()
235     dispatch_release(group);
236 }
237 
238 
239 
240 /*
241  dispatch source
242  */
243 - (IBAction)btnClick:(UIButton *)sender {
244 }
245 
246 
247 - (void)dealloc {
248     [_outletLabel1 release];
249     [_outletLabel2 release];
250     [_outletLabel3 release];
251     [_outletLabel4 release];
252     [super dealloc];
253 }
254 @end
原文地址:https://www.cnblogs.com/zouzf/p/2816691.html