多线程02-GCD 掌握
2015-06-15 13:51
323 查看
gcd的总结
三、GCD 1.队列和任务 1> 任务 :需要执行什么操作 * 用block来封装任务 2> 队列 :存放任务 * 全局的并发队列 : 可以让任务并发执行 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); * 自己创建的串行队列 : 让任务一个接着一个执行 dispatch_queue_t queue = dispatch_queue_create("cn.heima.queue", NULL); * 主队列 : 让任务在主线程执行 dispatch_queue_t queue = dispatch_get_main_queue(); 2.执行任务的函数 1> 同步执行 : 不具备开启新线程的能力 dispatch_sync... 2> 异步执行 : 具备开启新线程的能力 dispatch_async... 3.常见的组合(掌握) 1> dispatch_async + 全局并发队列 2> dispatch_async + 自己创建的串行队列 4.线程间的通信(掌握) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 执行耗时的异步操作... dispatch_async(dispatch_get_main_queue(), ^{ // 回到主线程,执行UI刷新操作 }); }); 5.GCD的所有API都在libdispatch.dylib,Xcode会自动导入这个库 * 主头文件 : #import <dispatch/dispatch.h> 6.延迟执行(掌握) 1> perform.... // 3秒后自动回到当前线程调用self的download:方法,并且传递参数:@"http://555.jpg" [self performSelector:@selector(download:) withObject:@"http://555.jpg" afterDelay:3]; 2> dispatch_after... // 任务放到哪个队列中执行 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); double delay = 3; // 延迟多少秒 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delay * NSEC_PER_SEC)), queue, ^{ // 3秒后需要执行的任务 }); 7.一次性代码(掌握) static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ // 这里面的代码,在程序运行过程中,永远只会执行1次 });
队列的使用
// // HMViewController.m // 08-GCD02-队列的使用(了解) // // Created by apple on 14-9-15. // Copyright (c) 2014年 heima. All rights reserved. // // dispatch_sync : 同步,不具备开启线程的能力 // dispatch_async : 异步,具备开启线程的能力 // 并发队列 :多个任务可以同时执行 // 串行队列 :一个任务执行完后,再执行下一个任务 // Foundation : OC // Core Foundation : C语言 // Foundation和Core Foundation框架的数据类型可以互相转换的 //NSString *str = @"123"; // Foundation //CFStringRef str2 = (__bridge CFStringRef)str; // Core Foundation //NSString *str3 = (__bridge NSString *)str2; // CFArrayRef ---- NSArray // CFDictionaryRef ---- NSDictionary // CFNumberRef ---- NSNumber // Core Foundation中手动创建的数据类型,都需要手动释放 // CFArrayRef array = CFArrayCreate(NULL, NULL, 10, NULL); // CFRelease(array); // // // CGPathRef path = CGPathCreateMutable(); // CGPathRetain(path); // // CGPathRelease(path); // CGPathRelease(path); /** 凡是函数名中带有create\copy\new\retain等字眼, 都应该在不需要使用这个数据的时候进行release GCD的数据类型在ARC环境下不需要再做release CF(Core Foundation)的数据类型在ARC\MRC环境下都需要再做release */ #import "HMViewController.h" @interface HMViewController () @end @implementation HMViewController - (void)viewDidLoad { [super viewDidLoad]; } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [self asyncSerialQueue]; } /** * async -- 并发队列(最常用) * 会不会创建线程:会,一般同时开多条 * 任务的执行方式:并发执行 */ - (void)asyncGlobalQueue { // 获得全局的并发队列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 将 任务 添加 全局队列 中去 异步 执行 dispatch_async(queue, ^{ NSLog(@"-----下载图片1---%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"-----下载图片2---%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"-----下载图片3---%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"-----下载图片4---%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"-----下载图片5---%@", [NSThread currentThread]); }); } /** * async -- 串行队列(有时候用) * 会不会创建线程:会,一般只开1条线程 * 任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务) */ - (void)asyncSerialQueue { // 1.创建一个串行队列 dispatch_queue_t queue = dispatch_queue_create("cn.heima.queue", NULL); // 2.将任务添加到串行队列中 异步 执行 dispatch_async(queue, ^{ NSLog(@"-----下载图片1---%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"-----下载图片2---%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"-----下载图片3---%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"-----下载图片4---%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"-----下载图片5---%@", [NSThread currentThread]); }); // 3.非ARC,需要释放创建的队列 // dispatch_release(queue); } /** * async -- 主队列(很常用) */ - (void)asyncMainQueue { // 1.主队列(添加到主队列中的任务,都会自动放到主线程中去执行) dispatch_queue_t queue = dispatch_get_main_queue(); // 2.添加 任务 到主队列中 异步 执行 dispatch_async(queue, ^{ NSLog(@"-----下载图片1---%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"-----下载图片2---%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"-----下载图片3---%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"-----下载图片4---%@", [NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"-----下载图片5---%@", [NSThread currentThread]); }); } /** * sync -- 主队列(不能用---会卡死) */ - (void)syncMainQueue { NSLog(@"syncMainQueue----begin--"); // 1.主队列(添加到主队列中的任务,都会自动放到主线程中去执行) dispatch_queue_t queue = dispatch_get_main_queue(); // 2.添加 任务 到主队列中 异步 执行 dispatch_sync(queue, ^{ NSLog(@"-----下载图片1---%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"-----下载图片2---%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"-----下载图片3---%@", [NSThread currentThread]); }); NSLog(@"syncMainQueue----end--"); } /**-------------------------------------华丽的分割线-----------------------------------------------------**/ /** * sync -- 并发队列 * 会不会创建线程:不会 * 任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务) * 并发队列失去了并发的功能 */ - (void)syncGlobalQueue { // 获得全局的并发队列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 将 任务 添加到 全局并发队列 中 同步 执行 dispatch_sync(queue, ^{ NSLog(@"-----下载图片1---%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"-----下载图片2---%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"-----下载图片3---%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"-----下载图片4---%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"-----下载图片5---%@", [NSThread currentThread]); }); } /** * sync -- 串行队列 * 会不会创建线程:不会 * 任务的执行方式:串行执行(一个任务执行完毕后再执行下一个任务) */ - (void)syncSerialQueue { // 创建一个串行队列 dispatch_queue_t queue = dispatch_queue_create("cn.heima.queue", NULL); // 将 任务 添加到 串行队列 中 同步 执行 dispatch_sync(queue, ^{ NSLog(@"-----下载图片1---%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"-----下载图片2---%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"-----下载图片3---%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"-----下载图片4---%@", [NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"-----下载图片5---%@", [NSThread currentThread]); }); } @end
线程的基本通信
// // HMViewController.m // 09-GCD03-线程间的通信(掌握) // // Created by apple on 14-9-15. // Copyright (c) 2014年 heima. All rights reserved. // // 需要设置按钮的image和backgroundImage,建议先把按钮类型改为custom,才能保证设置成功 // 属性名不能以new开头 // 只有在init开头的构造方法中,才允许对self进行赋值 #define HMGlobalQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) #define HMMainQueue dispatch_get_main_queue() #import "HMViewController.h" @interface HMViewController () @property (weak, nonatomic) IBOutlet UIButton *button; @property (weak, nonatomic) IBOutlet UIImageView *newImageView; @end @implementation HMViewController - (void)viewDidLoad { [super viewDidLoad]; [self newImageView]; // NSObject *obj = [NSObject new]; // // [[NSObject alloc] init]; // Do any additional setup after loading the view, typically from a nib. } - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { dispatch_async(HMGlobalQueue, ^{ NSLog(@"donwload---%@", [NSThread currentThread]); // 1.子线程下载图片 NSURL *url = [NSURL URLWithString:@"http://d.hiphotos.baidu.com/image/pic/item/37d3d539b6003af3290eaf5d362ac65c1038b652.jpg"]; NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:data]; // 2.回到主线程设置图片 dispatch_async(HMMainQueue, ^{ NSLog(@"setting---%@ %@", [NSThread currentThread], image); [self.button setImage:image forState:UIControlStateNormal]; }); }); } @end
相关文章推荐
- Flex字符串比较 还有Flex字符串操作
- ASP Cookies操作的详细介绍与实例代码
- perl数据库添加、删除、更新、查询操作例子
- 总结的5个C#字符串操作方法分享
- C#操作XML文件实例汇总
- C#中父窗口和子窗口之间控件互操作实例
- C#操作PowerPoint的方法
- SQL语句 操作全集 学习mssql的朋友一定要看
- linux mysql 安装与操作
- C语言实现带头结点的链表的创建、查找、插入、删除操作
- 使用PHPExcel操作Excel用法实例分析
- C#队列Queue用法实例分析
- C# WORD操作实现代码
- 解析c++中的默认operator=操作的详解
- 比较全的一个C#操作word文档示例
- C#实现对图片文件的压缩、裁剪操作实例
- asp下利用fso实现文件夹或文件移动改名等操作函数
- php操作xml入门之xml基本介绍及xml标签元素
- PHP SESSION的增加、删除、修改、查看操作
- Javascript select控件操作大全(新增、修改、删除、选中、清空、判断存在等)