• 多线程GCD-牛逼中央调度器


     

    多线程

    个人理解
    一般一个程序有一个主线程,主要控制点击,UI界面,如果执行一个耗时的操作的话,用户体验相当垃圾,因此我们会讲执行耗时的操作方到一个新的线程
    ,但是用线程的话要提防线程的安全问题,如(共享资源)导致数据错乱
    如售票任务,银行存钱等(解决办法使用@synchronized(锁对象))
     
    苹果提供了一个GCD 叫牛逼中央调度器
    其工作原理是将我们要执行的耗时操作放到一个队列中去,GCD提供的方法去队列中取出任务开启线程执行,因此线程我们就不用去写什么代码
     
    GCD有两个执行任务的函数一个是同步函数dispatch_sync,一个是异步函数
    dispatch_asysc,
    同步:就是在当前线程中执行,异步:在另一个线程中执行
     
    GCD的队列也可以分为两个:
    1  一个是并发队列:可以让多个任务并发(同时)执行(会自动开启多个线程)

    GCD默认已经提供了全局的并发队列,供整个应用使用,不需要手动创建

    使用dispatch_get_global_queue函数获得全局的并发队列

    说明:全局并发队列的优先级

    #define DISPATCH_QUEUE_PRIORITY_HIGH 2 // 高

    #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 // 默认(中)

    #define DISPATCH_QUEUE_PRIORITY_LOW (-2) // 低

    #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN // 后台

    2  一个是串行队列:就是让任务依次执行(在一个线程中)
    串行队列有两种创建队列的函数:
    1>dispatch_queue_t dispatch_queue_create(创建串行队列)
    2>dispatch_queue_t dispatch_get_main_queue(主队列,跟主线程相关联的队列)

    代码示例: 

    用异步函数往并发队列中添加任务

    #import "LLBViewController.h"
    
    @interface LLBViewController ()
    
    @end
    
    @implementation LLBViewController
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
        // 1,获取全局并发队列
        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(@"下载电影2-----%@", [NSThread currentThread]);
        });
        dispatch_async(queue, ^{
            
            NSLog(@"下载电影3-----%@", [NSThread currentThread]);
        });
        
        // 打印主线程
        NSLog(@"主线程-----%@",[NSThread currentThread]);
    }

     

    注意:同时开启3个线程 

    2>异步串行队列,有开启新的线程

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        
       // 创建串行队列
        dispatch_queue_t queue = dispatch_queue_create("niubiGCD", NULL);
        // 第一个参数为串行队列的名称,是c语言字符串
        // 第二个为队列的属性,一般说串行队列不用赋值任何属性,传null
        
        // 添加任务到队列中执行
        dispatch_async(queue, ^{
            
            NSLog(@"下载图片1-----%@", [NSThread currentThread]);
        });
        
        dispatch_async(queue, ^{
            
            NSLog(@"下载图片2-----%@", [NSThread currentThread]);
        });
        
        // 非ARC需要释放队列 凡是new,alloc,retain,create都需要释放内存,因为创建对象的时候系统分配了内存
        NSLog(@"主线程------%@", [NSThread currentThread]);
    }
    2014-10-21 16:26:11.354 GCD[2347:907] 主线程------<NSThread: 0x7541aa0>{name = (null), num = 1}
    2014-10-21 16:26:11.354 GCD[2347:1103] 下载图片1-----<NSThread: 0x757d2e0>{name = (null), num = 3}
    2014-10-21 16:26:11.356 GCD[2347:1103] 下载图片2-----<NSThread: 0x757d2e0>{name = (null), num = 3}

    注意:开启了新线程,但新的线程只有一个;

    3>同步函数并行队列添加任务

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        NSLog(@"主线程--------%@",[NSThread currentThread]);
        
        // 同步函数并发队列中添加任务
        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]);
        });
    }
    2014-10-21 16:34:55.725 GCD[2374:907] 主线程--------<NSThread: 0x762a0a0>{name = (null), num = 1}
    2014-10-21 16:34:55.726 GCD[2374:907] 下载电影1-----<NSThread: 0x762a0a0>{name = (null), num = 1}
    2014-10-21 16:34:55.726 GCD[2374:907] 下载电影2-----<NSThread: 0x762a0a0>{name = (null), num = 1}
    

     注意:同步函数不具备开启新线程的能力,利用了当前线程

    4>同步函数串行队列中添加任务

    - (void)viewDidLoad
    {
        [super viewDidLoad];
    	
        NSLog(@"主线程--------%@",[NSThread currentThread]);
        
        // 同步函数串行队列中添加任务
        dispatch_queue_t queue = dispatch_queue_create("niubiGDC", NULL);
        
        // 将任务添加到队列中
        dispatch_sync(queue, ^{
            
            NSLog(@"下载电影1-----%@", [NSThread currentThread]);
        });
        // 将任务添加到队列中
        dispatch_sync(queue, ^{
            
            NSLog(@"下载电影2-----%@", [NSThread currentThread]);
        });
    }
    
    2014-10-21 16:38:36.116 GCD[2391:907] 主线程--------<NSThread: 0x763e4a0>{name = (null), num = 1}
    2014-10-21 16:38:36.117 GCD[2391:907] 下载电影1-----<NSThread: 0x763e4a0>{name = (null), num = 1}
    2014-10-21 16:38:36.118 GCD[2391:907] 下载电影2-----<NSThread: 0x763e4a0>{name = (null), num = 1}
    

     注意:不会开启新的线程,还是当前主线程

  • 相关阅读:
    小甲鱼PE详解之输入表(导出表)详解(PE详解09)
    小甲鱼PE详解之输入表(导入表)详解2(PE详解08)
    小甲鱼PE详解之输入表(导入表)详解(PE详解07)
    小甲鱼PE详解之区块描述、对齐值以及RVA详解(PE详解06)
    小甲鱼PE详解之区块表(节表)和区块(节)续(PE详解05)
    小甲鱼PE详解之区块表(节表)和区块(节)(PE详解04)
    天大 ACM 1090. City hall
    C++中关于cin、cin.get()、cin.getline()、getline()、gets()等函数的用法
    Integer Inquiry -TJU1112
    天大acm 题号1002 Maya Calendar
  • 原文地址:https://www.cnblogs.com/-boy/p/4040639.html
Copyright © 2020-2023  润新知