iOS 多线程( GCD NSThread )

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

    });
    
原文地址:https://www.cnblogs.com/wangbinbin/p/4800042.html