• 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();
    
        });
        
    
  • 相关阅读:
    soap-学习
    Redis教程
    Java 不可变对象
    java volatile
    Go语言
    mongodb 基础语法
    Linux 命令大全
    Java json字符串对比
    sqlserver 数据库阻塞和死锁
    http 和 https 的区别
  • 原文地址:https://www.cnblogs.com/wangbinbin/p/4800042.html
Copyright © 2020-2023  润新知