GCD

GCD的基本思想是将操作放在队列中执行

纯C语言

优点

1.为多核的并行运算提出了解决方案

2.自动利用更多的CPU内核

3.自动管理线程的生命周期(创建线程,调度任务,消毁线程)

4.程序员只需要告诉GCD想要执行什么任务,不需要编写任何线程管理代码

二 .任务和队列

GCD使用步骤

*定制任务(确定想做的事情)

*将任务添加到队列中

GCD会自动将队列中的任务取出来,放到对应的线程中执行

任务的取出遵循队列的FIFO原则:先进先出,后进后出 与栈的区别 先进后出

*GCD中有两种方式执行任务的函数

1.同步的方式执行任务

dispatch_sync(<#dispatch_queue_t queue#>, <#^(void)block#>)

queue :队列

block:任务

2.异步的方式执行任务

dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>)

queue :队列

block:任务

同步和异步区别

同步:在当前线程中执行(不具备开启线程)

异步:在另一条线程中执行(具备开启线程的能力)

GCD的队列可以分为2大类

1.并发队列(Concurrent DISpathch Queue)

可以让多个任务并发(同时)执行(自动开启多个线程同时执行任务)

并发功能只有异步(dispatch_async)函数下才有效

2串行队列(serial Dispatch Queue)

让任务一个接着一个地执行(一个任务执行才可以完成下个任务)

 

 凡事函数名带有creat retain copy new 等字眼 都需要在不需要的时候进行release

 *主队列 (跟主线程相关的队列)

主队列GCD 自带的一种特殊的串行队列

放在主队列中的任务,都放到主线程中执行

 

********* 使用dispatch_sync 同步函数,不能主线程中往主队列dispatch_get_main_queue() 添加任务因为在同步函数中会在主线程中是按顺序执行的 会照成死循环

touchesBegan 中添加到主线程队列中 GCD4也添加到主线程队列 touchesBegan等待GCD4完成 GCD4 等待touchesBegan完成

如果是异步dispatch_async 可以缓一缓 不是死循环

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    [self GCD4];
}

#pragma mark 主(线程)队列 保证操作在主线程中执行
-(void)GCD4
{
    //每个应用程序只有一个主线程
    //为什么需要主线程 ,所有UI的更新工作 都必须在主线程上工作
    dispatch_queue_t q=dispatch_get_main_queue()
    ;
    //异步在主线程 在主线程上运行
    for (int i=0; i<15; i++) {
        dispatch_sync(q, ^{//同步顺序执行仍然依次执行
            //                NSLog(@"",);//当前线程;
            NSLog(@"%@ %d",[NSThread currentThread],i);
        });
    }

}

 

#pragma mark dispatch_group_async组 只有等到组内的所有任务都执行完才会调用dispatch_group_notify
-(void)creatGround
{
    
    dispatch_group_t que= dispatch_group_create();
    dispatch_group_notify(que, dispatch_get_main_queue(), ^{
        NSLog(@"------------");
    });
    dispatch_group_async(que, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"=====");
    });
    dispatch_group_async(que, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSLog(@"=====");
    });
}

 

#pragma mark 主(线程)队列 保证操作在主线程中执行
-(void)GCD4
{
    //每个应用程序只有一个主线程
    //为什么需要主线程 ,所有UI的更新工作 都必须在主线程上工作
    dispatch_queue_t q=dispatch_get_main_queue()
    ;
    //异步在主线程 在主线程上运行
    
    for (int i=0; i<15; i++) {
        
        //主线程是有工作的 阻塞 而且
        //异步任务,在主线程上运行,继续保持队列
        
        dispatch_sync(q, ^{//同步顺序执行仍然依次执行
            //                NSLog(@"",);//当前线程;
            NSLog(@"%@ %d",[NSThread currentThread],i);
        });
    }
//
    
    
    for (int i=0; i<5; i++) {
        dispatch_async(q, ^{//异步任务,并发执行,当是如果在串行队列依次按顺序执行
            
            NSLog(@"%@ %d",[NSThread currentThread],i);
        });
    }
//
}

#pragma mark 全局队列(苹果为了方便多线程的设计 提供一个全局队列,供所有APP共同使用)
-(void)GCD3{
    //全局队列与并行队列区别
//    1 不需要创建 直接get就能用
//    2.两个队列的执行效果相同
//    3全局队列没有名称 调试时 无法确定对队列
    dispatch_queue_t q=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);//优先级
 
//    for (int i=0; i<5; i++) {
//        dispatch_sync(q, ^{//同步顺序执行仍然依次执行
//            //                NSLog(@"",);//当前线程;
//            NSLog(@"%@ %d",[NSThread currentThread],i);
//        });
//    }
//
    for (int i=0; i<5; i++) {
        dispatch_async(q, ^{//异步任务,并发执行,当是如果在串行队列依次按顺序执行
            NSLog(@"%@ %d",[NSThread currentThread],i);
            dispatch_async(dispatch_get_main_queue(), ^{
                self.textfrield.text=@"12345678912345678";
            });
            
        });
    }
    


}

#pragma mark 串行(一个接一个排队跑步,保持dui)
-(void)GCD
{
    //将操作放到队列中
    //在C语言函数中,定义类型,绝大多数的结尾时_t或者ref
    //使用串行队列,的异步任务非常有用,新建子线程是有开销的,不能无止境新建线程
    //既保证效率只有(新建一个子线程)要能够实现并发
    
    dispatch_queue_t q=dispatch_queue_create("zefeng", DISPATCH_QUEUE_SERIAL);
    
    //串行队列的同步任务,会在 “主线程上运行”
    // 少用
    for (int i=0; i<5; i++) {
        dispatch_sync(q, ^{//同步顺序执行仍然依次执行
            //                NSLog(@"",);//当前线程;
            NSLog(@"%@ %d",[NSThread currentThread],i);
        });
    }
    
    

    for (int i=0; i<5; i++) {
        dispatch_async(q, ^{//异步任务,并发执行,当是如果在串行队列依次按顺序执行
            
              NSLog(@"%@ %d",[NSThread currentThread],i);
        });
    }
 
//    dispatch_release(q);
    
}
#pragma mark 并行(并排跑)
-(void)GCD1{
    //特点:没有队形,执行顺序程序员不能控制
    //应用场景:并发执行任务,没有先后顺序关系
    //并行队列容易出错!并行队列不能控制顺序 控制新建线程的数量
    
    dispatch_queue_t q=dispatch_queue_create("xiefeng", DISPATCH_QUEUE_CONCURRENT);//concurrent
    
    for (int i=0; i<3; i++) {
        dispatch_sync(q, ^{//同步顺序执行仍然依次执行
            //                NSLog(@"",);//当前线程;
            NSLog(@"%@ %d",[NSThread currentThread],i);
        });
    }
    for (int i=0; i<3; i++) {
        dispatch_async(q, ^{//异步
            NSLog(@"%@ %d",[NSThread currentThread],i);

        });
    }
}

 

 

 

 

 

操作使用block定义

队列负责调度任务执行所在的线程以及具体的执行时间

队列的特点先进先出,新添加至队列的操作都会排在队尾

提示

GCD的函数都是以(dispatch 分派 调度)开头的

队列

dispatch_queue_t

   串行队列 队列中的任务只会按顺序执行

   并行队列 队列中任务通常会并发执行

dispatch_async 异步操作 会并发执行,无法确定任务的执行顺序

dispatch_sync  同步操作 会依次顺序执行,能够决定任务的执行顺序

队列不是线程 也不是CPU 队列负责调度 谁空闲就把任务给谁

多线程的目的是为了在CPU上实现快速切换  

 

你可能感兴趣的:(GCD)