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();
});