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