iOS--多线程之GCD(Grand Central Dispatch)

本文详细介绍了GCD中的任务和队列概念,包括同步与异步任务的区别,以及并发队列和串行队列的工作原理。此外,还提供了如何创建不同类型的队列及其实现线程间通信的具体示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

做一下整理,与大家分享,不足之处请留言:

GCD中最核心的是任务和队列,使用时要先创建任务,然后将任务添加到队列中

创建任务时有两种方式:

同步:只能在当前线程中执行任务,不具备开启新线程的能力

 

         dispatch_sync(dispatch_queue_t queue, dispatch_block_t block);

异步:可以在新的线程中执行任务,具备开启新线程的能力

         dispatch_async(dispatch_queue_t queue, dispatch_block_t block);

队列有两类:

并发队列(Concurrent Dispatch Queue)

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

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

串行队列(Serial Dispatch Queue)

             让任务一个接着一个地执行(一个任务执行完毕后,再执行下一个任务)

创建队列

创建并发队列

dispatch_queue_t queue = dispatch_queue_create("作用.queue", DISPATCH_QUEUE_CONCURRENT);

获取全局的并发队列

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

创建串行队列

dispatch_queue_t queue = dispatch_queue_create("作用.queue", DISPATCH_QUEUE_SERIAL);

获取主队列:主队列是GCD自带的一种特殊的串行队列,放在主队列中的任务,都会放到主线程中执行

dispatch_queue_t queue = dispatch_get_main_queue();

从网上找的图,可以借鉴:

注:在使用sync函数往当前串行队列中添加任务,会卡住当前的串行队列

线程之间的通信:获得全局的并发队列,并创建一个异步任务(开启一个新的子线程)执行耗时操作,完成    之后回到主线程,创建UI刷新界面

 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

 dispatch_async(queue, ^{

    // 执行耗时的异步操作...

      dispatch_async(dispatch_get_main_queue(), ^{

        // 回到主线程,执行UI刷新操作

        });   });

 

dispatch_once: 在程序运行过程中只被执行1次

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

    // 只执行1次的代码(这里面默认是线程安全的)

});

延时执行 1.  [self performSelector:@selector(downLoad) withObject:nil afterDelay:3.0];

       2. dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC)),      dispatch_get_main_queue(), ^{

    // 3秒后异步执行这里的代码...      });

 

队列组 异步执行多个耗时的操作,都执行完毕后,再回到主线程执行操作

一、耗时操作不涉及网络请求

dispatch_group_t group =  dispatch_group_create();

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ // 执行1个耗时的异步操作 (不涉及网络请求)

});

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{// 执行1个耗时的异步操作(不涉及网络请求)

});

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

    // 等前面的异步操作都执行完毕后,回到主线程...

});

 二、涉及到网络请求(上传多张图片)

  //创建队列组
    dispatch_group_t group = dispatch_group_create();
    //创建并发队列  
    dispatch_queue_t queue = dispatch_queue_create("upload", DISPATCH_QUEUE_CONCURRENT);

    AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];

//设置信号量
 dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
   [manager POST:urlMD5Com parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {

    NSDateFormatter *formatter=[[NSDateFormatter alloc]init];
    formatter.dateFormat=@"yyyyMMddHHmmss";
    NSString *str=[formatter stringFromDate:[NSDate date]];
    NSString *fileName=[NSString stringWithFormat:@"%@.jpg",str];
    //传的图片数据放这里
    [formData appendPartWithFileData:data name:@"file" fileName:fileName mimeType:@"image/png"];
            } progress:^(NSProgress * _Nonnull uploadProgress) {
                
                
            } success:^(NSURLSessionDataTask * _Nonnull task, NSMutableDictionary *responseObject) {
                dispatch_semaphore_signal(semaphore);
                //拿到所需要的数据
               
                
            } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                
                dispatch_semaphore_signal(semaphore);
                //解析出后台返回信息
                NSDictionary *errorInfo;
                if ([error userInfo][@"com.alamofire.serialization.response.error.data"]) {
                    errorInfo = [NSJSONSerialization JSONObjectWithData:([error userInfo][@"com.alamofire.serialization.response.error.data"]) options:NSJSONReadingMutableLeaves error:NULL];
                }
                NSLog(@"errorInfo--errorInfo:%@",errorInfo);
            }];
            
            dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
        });

 //等前面的任务执行完毕后,会自动执行该任务 
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        
     //上传完图片后的操作
    });

 

 

 

线程的依赖:

- (void)addMission1
{
    /**任务1,2并行执行,执行完后任务3执行*/
    dispatch_group_t group =dispatch_group_create();
    dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
        
        NSLog(@"任务1");
        
        //回到主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            
            
        });
    });
    
    dispatch_group_async(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
        NSLog(@"任务2");
        
        //回到主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            
            
        });
    });
    
    dispatch_group_notify(group,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{
        NSLog(@"任务3");
        //回到主线程
        dispatch_async(dispatch_get_main_queue(), ^{
            
            
        });
    });
    
}

- (void)addMission2
{
    /*方法2*/
    /*
     dispatch_barrier_async
     任务1,2并行执行,执行完后任务3执行,执行完后任务4,5并行执行。*/
    dispatch_queue_t myqueue =dispatch_queue_create("myqueue.queue",DISPATCH_QUEUE_CONCURRENT);
    dispatch_async(myqueue, ^{
        NSLog(@"任务1");
    });
    
    dispatch_async(myqueue, ^{
        NSLog(@"任务2");
    });
    
    dispatch_barrier_async(myqueue, ^{
        NSLog(@"任务3");
    });
    
    dispatch_async(myqueue, ^{
        NSLog(@"任务4");
    });
    dispatch_async(myqueue, ^{
        NSLog(@"任务5");
    });
}

 

 

 

 

 

 

 

 

 

转载于:https://my.oschina.net/huangyn/blog/868697

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值