1.NSThread
①.开线程的几种方式
*先创建, 后启动
//开启线程 NSThread *thread =[[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil]; //启动 [thread start]; //直接启动 [NSThread detachNewThreadSelector:@selector(<#selector#>) toTarget:self withObject:nil];
②.其他用法
//获取当前线程 NSThread *current =[NSThread currentThread]; //获得主线程 + (NSThread* )mainThread; //线程间通信 (从子线程回到主线程)
- (void)performSelectorOnMainThread:<#(SEL)#> withObject:<#(id)#> waitUntilDone:<#(BOOL)#>
CGD(重点)
1.队列的类型
*并发队列:可以同时执行多个任务
获得全局的并发队列:dispatch_get_global_queue(<#long identifier#>, <#unsigned long flags#>)
*串行队列:一个任务执行完了才能执行下一个任务
a.自己创建:dispatch_queue_create
b.主队列:dispatch_get_main_queue
2.执行任务的方法类型
*同步(sync)执行:只能在当前线程执行任务
*异步(async)执行:可以多个线程执行任务(系统会自动给你开辟的,你只要写要做什么)
3.了解队列的方法配合使用
*异步并发队列
//获取全局的并发队列 //第一个参数代表优先级 dispatch_queue_t queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //2.添加任务到队列中,执行 任务 dispatch_async(queue, ^{ NSLog(@"------下载图片1-------%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"------下载图片1-------%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"------下载图片1-------%@",[NSThread currentThread]); }); //总结:同时开启了3个线程
*异步串行队列
//1.创建串行队列 dispatch_queue_t queue= dispatch_queue_create("com.itheima.queue ", NULL); dispatch_async(queue, ^{ NSLog(@"------下载图片1-------%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"------下载图片1-------%@",[NSThread currentThread]); }); dispatch_async(queue, ^{ NSLog(@"------下载图片1-------%@",[NSThread currentThread]); }); //总结:只会开一个线程;
*同步串行
//创建串行队列 dispatch_queue_t queue=dispatch_queue_create("wangbinbin.queue", NULL); //2.添加任务到队列中,执行 任务 dispatch_sync(queue, ^{ NSLog(@"------下载图片1-------%@",[NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"------下载图片2-------%@",[NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"------下载图片3-------%@",[NSThread currentThread]); }); //总结:不会开辟线程 只在当前线程执行(当前线程为主线程, dispatch_sync是在主线程)
*同步并发队列
//获取全局的并发队列 //第一个参数代表优先级 dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //2.添加任务到队列中,执行 任务 dispatch_sync(queue, ^{ NSLog(@"------下载图片1-------%@",[NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"------下载图片2-------%@",[NSThread currentThread]); }); dispatch_sync(queue, ^{ NSLog(@"------下载图片2-------%@",[NSThread currentThread]); }); //总结:不会开启新的线程,并发队列失去了并发功能
GCD其他常用方法
1.从子线程回到主线程
NSLog(@"%@",[NSThread currentThread]); //异步并发队列 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSLog(@"------%@",[NSThread currentThread]); //请求图片 NSURL *url =[NSURL URLWithString:@"http://img.taopic.com/uploads/allimg/110812/1820-110Q20K01549.jpg"]; NSData *data =[NSData dataWithContentsOfURL:url]; UIImage *image=[UIImage imageWithData:data]; //回到主线程显示图片 dispatch_async(dispatch_get_main_queue(), ^{ NSLog(@"+++%@",[NSThread currentThread]); self.imgView.image=image; }); });
2.一次性代码
//一次性代码 单例里面用得到 static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ NSLog(@"只执行一次,"); });
3.延时操作
//延时操作 2秒后 //计算时间 dispatch_time_t when=dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)); //会在when这个时间点,执行queue(队列可以自己选择) dispatch_after(when, dispatch_get_main_queue(), ^{ NSLog(@"瞧我!!"); });
4.队列组
有这么一种需求
首先:分别异步执行2个耗时的操作
其次:等2个异步操作都执行完毕后,再回到主线程执行操作
//创建一个组 dispatch_group_t group =dispatch_group_create(); //开启一个任务下载图片1 __block UIImage *image1 =nil; dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ image1 =[self requestImageWithUrl:@"http://d.hiphotos.baidu.com/image/pic/item/faedab64034f78f09c7428247d310a55b2191ced.jpg"]; }); //开启一个任务下载图片2 __block UIImage *image2 =nil; dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ image2 =[self requestImageWithUrl:@"http://b.hiphotos.baidu.com/image/h%3D360/sign=502eb6fad954564efa65e23f83df9cde/80cb39dbb6fd5266c96cb6fdaf18972bd5073697.jpg"]; }); //等group中的所有任务都执行完毕,在执行其他操作 dispatch_group_notify(group, dispatch_get_main_queue(), ^{ self.UIImageView1.image=image1; self.UIImageView2.image=image2; //合并2个image UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 100), NO, 0); [image1 drawInRect:CGRectMake(0, 0, 100, 100)]; [image2 drawInRect:CGRectMake(100, 0, 100, 100)]; self.bigUiImageView.image=UIGraphicsGetImageFromCurrentImageContext(); //关闭上下文 UIGraphicsEndImageContext(); });