美文网首页
GCD之同步异步与串行并行队列详解

GCD之同步异步与串行并行队列详解

作者: Ariest | 来源:发表于2016-06-13 23:10 被阅读0次

    同步只能在当前线程中执行任务,不具备开启新线程的能力。异步可以在新线程中执行任务,具备开启新线程的能力。
    多线程:一个进程可以开启多条线程,每条线程可以执行不同的任务。实质上在同一时间,CPU只能处理一条线程,CPU快速在多线程间调度,产生并发执行假象。

    多线程实例应用

    -(void)test06
    {
        #异步主队列: 异步不会阻塞主线程 主队列任务必须放在主线程执行
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"%@--A",[NSThread currentThread]);
        });
        
        #第一步: 主线程执行 输出B
        NSLog(@"%@--B",[NSThread currentThread]);
    
        dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
        
        #同步全局并发队列: 同步会阻塞主线程 第二步: 输出C 
        dispatch_sync(queue, ^{
            NSLog(@"%@--C",[NSThread currentThread]);
        });
        
        #异步全局并发队列: 开启新线程执行任务 未阻塞主线程 
        dispatch_async(queue, ^{    
            NSLog(@"%@--D",[NSThread currentThread]);
        });
        
        #异步主队列: 异步不会阻塞主线程 主队列任务必须放在主线程执行
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"%@--E",[NSThread currentThread]);
        });
        
        #此方法主线程执行  相当于异步主队列
        [self performSelector:@selector(testMethod) withObject:nil afterDelay:0];
        
        #第三步: 主队列执行 输出F
        NSLog(@"%@--F",[NSThread currentThread];
    
        /*
            主队列任务顺序: G->E->A
            输出结果为:
            B C F D A E G
        */
        
    }
    
    
    -(void)testMethod{
        
        NSLog(@"%@--G",[NSThread currentThread]);
    }
    
    
    #打印结果
     {number = 1, name = main}--B
     {number = 1, name = main}--C
     {number = 1, name = main}--F
     {number = 3, name = (null)}--D
     {number = 1, name = main}--A
     {number = 1, name = main}--E
     {number = 1, name = main}--G
    
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        [self test01];
        [self test02];
        [self test03];
        [self test04];
        [self test05];
    }
    -(void)test05{
        NSOperationQueue *queue=[[NSOperationQueue alloc] init];
        NSBlockOperation *operationA=[NSBlockOperation blockOperationWithBlock:^{
            NSLog(@"%@--下载第A张图片",[NSThread currentThread]);
        }];
        NSBlockOperation *operationB=[NSBlockOperation blockOperationWithBlock:^{
            
            NSLog(@"%@--下载第B张图片",[NSThread currentThread]);
        }];
        
        NSBlockOperation *operationC=[NSBlockOperation blockOperationWithBlock:^{
            
            NSLog(@"%@--下载第C张图片",[NSThread currentThread]);
        }];
        
    #    [queue addOperation:operationA];
    #    [queue addOperation:operationB];
    #    [queue addOperation:operationC];
       
        #设置依赖 按需求A B C 顺序执行
        [operationB addDependency:operationA];
        [operationC addDependency:operationB];
        
        #添加任务到队列
        [queue addOperation:operationA];
        [queue addOperation:operationB];
        [queue addOperation:operationC];
    }
    
    -(void)test04{
        
        NSOperationQueue *queue=[[NSOperationQueue alloc] init];
        
        #设置最大并发数
    #    queue.maxConcurrentOperationCount=1;
        
        NSBlockOperation *operation1=[NSBlockOperation blockOperationWithBlock:^{
            
            NSLog(@"%@--下载第一张图片",[NSThread currentThread]);
        }];
        
        NSBlockOperation *operation2=[NSBlockOperation blockOperationWithBlock:^{
            
            NSLog(@"%@--下载第二张图片",[NSThread currentThread]);
        }];
        
        NSBlockOperation *operation3=[NSBlockOperation blockOperationWithBlock:^{
            
            NSLog(@"%@--下载第三张图片",[NSThread currentThread]);
        }];
        
        #InvocationOperation
        NSInvocationOperation *operation4=[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downloadOperation) object:nil];
        
        #添加操作到队列
        [queue addOperation:operation1];
        [queue addOperation:operation2];
        [queue addOperation:operation3];
        [queue addOperation:operation4];
        
        [queue addOperationWithBlock:^{
            
            NSLog(@"%@--下载第四张图片",[NSThread currentThread]);
        }];
        
        [queue addOperationWithBlock:^{
            
            NSLog(@"%@--下载第五张图片",[NSThread currentThread]);
        }];
        
    #    [queue cancelAllOperations];
    
    }
    
    -(void)downloadOperation{
        
        NSLog(@"downloadOperation--%@",[NSThread currentThread]);
    }
    
    -(void)test03{
        
        dispatch_group_t group=dispatch_group_create();
        
        dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        
        #下载第一张图片
        static UIImage *image1=nil;
    #    __block UIImage *image1=nil;
        dispatch_group_async(group, queue, ^{
            
            NSURL *url1=[NSURL URLWithString:@"http:#pic1.nipic.com/2008-12-25/2008122510134038_2.jpg"];
            NSData *data1=[NSData dataWithContentsOfURL:url1];
            image1=[UIImage imageWithData:data1];
            
            NSLog(@"image1--%@",[NSThread currentThread]);
        });
        
        #下载第二张图片
        static UIImage *image2=nil;
        #    __block UIImage *image2=nil;
        dispatch_group_async(group, queue, ^{
           
            NSURL *url2=[NSURL URLWithString:@"https:#www.baidu.com/img/bd_logo1.png"];
            NSData *data2=[NSData dataWithContentsOfURL:url2];
            image2=[UIImage imageWithData:data2];
            
            NSLog(@"image2--%@",[NSThread currentThread]);
        });
    
        
        dispatch_group_notify(group, queue, ^{
           
            NSLog(@"notify--%@",[NSThread currentThread]);
            
            #开启上下文
            UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0.0);
            
            #绘制第一张图片
            CGFloat image1W=image1.size.width;
            CGFloat image1H=image1.size.height;
            [image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
            
            #绘制第二张图片
            CGFloat image2W=image2.size.width;
            CGFloat image2H=image2.size.height;
            [image2 drawInRect:CGRectMake(image1W-image2W, image1H-image2H, image2W, image2H)];
            
            #获取绘制好的图片
            UIImage *image=UIGraphicsGetImageFromCurrentImageContext();
            
            #关闭上下文
            UIGraphicsEndImageContext();
            
            
            #回主线程刷新界面
            dispatch_async(dispatch_get_main_queue(), ^{
    
                NSLog(@"async--%@",[NSThread currentThread]);
                 self.imageView.image=image;
            });
    
        });
        
    }
    
    -(void)test02{
        
        #第一张图片
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
            NSURL *url1=[NSURL URLWithString:@"http:#pic1.nipic.com/2008-12-25/2008122510134038_2.jpg"];
            NSData *data1=[NSData dataWithContentsOfURL:url1];
            self.image1=[UIImage imageWithData:data1];
            
            [self mergerImage];
            
        });
        
        
        #第二张图片
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            
            NSURL *url2=[NSURL URLWithString:@"https:#www.baidu.com/img/bd_logo1.png"];
            NSData *data2=[NSData dataWithContentsOfURL:url2];
            self.image2=[UIImage imageWithData:data2];
            
            [self mergerImage];
        });
        
    }
    
    #合并图片
    -(void)mergerImage{
        
        if (self.image1 == nil || self.image2 == nil) {
            
            return;
        }else{
            
            UIGraphicsBeginImageContextWithOptions(self.image1.size, NO, 0.0);
            
            #绘制第一张图
            CGFloat image1W=self.image1.size.width;
            CGFloat image1H=self.image1.size.height;
            [self.image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
            
            #绘制第二张图
            CGFloat image2W=self.image2.size.width;
            CGFloat image2H=self.image2.size.height;
            [self.image2 drawInRect:CGRectMake(image1W-image2W, image1H-image2H, image2W, image2H)];
            
            #获取绘制后的图片
            UIImage *image=UIGraphicsGetImageFromCurrentImageContext();
            
            UIGraphicsEndImageContext();
            
            #UI界面显示
            dispatch_async(dispatch_get_main_queue(), ^{
               
                self.imageView.image=image;
            });
            
        }
    }
    
    
    -(void)test01{
        
        dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
        
        dispatch_async(queue, ^{
            
            NSLog(@"%@--global_queue",[NSThread currentThread]);
            
            #下载第一张图片
            NSURL *url1=[NSURL URLWithString:@"http:#pic1.nipic.com/2008-12-25/2008122510134038_2.jpg"];
            NSData *data1=[NSData dataWithContentsOfURL:url1];
            UIImage *image1=[UIImage imageWithData:data1];
            
            #下载第二张图片
            NSURL *url2=[NSURL URLWithString:@"https:#www.baidu.com/img/bd_logo1.png"];
            NSData *data2=[NSData dataWithContentsOfURL:url2];
            UIImage *image2=[UIImage imageWithData:data2];
            
            #合并图片
            
            UIGraphicsBeginImageContextWithOptions(image1.size, NO, 0);
            
            #绘制第一张图片
            CGFloat image1W=image1.size.width;
            CGFloat image1H=image1.size.height;
            [image1 drawInRect:CGRectMake(0, 0, image1W, image1H)];
            
            #绘制第二张图片
            CGFloat image2W=image2.size.width*0.5;
            CGFloat image2H=image2.size.height*0.5;
            [image2 drawInRect:CGRectMake(image1W-image2W, image1H-image2H, image2W, image2H)];
            
            #获取绘制好的合成图片
            UIImage *image=UIGraphicsGetImageFromCurrentImageContext();
            
            UIGraphicsEndImageContext();
            
            dispatch_async(dispatch_get_main_queue(), ^{
                
                 NSLog(@"%@--main_queue",[NSThread currentThread]);
                
                self.imageView.image=image;
                
            });
            
        });
    
    }
    
    

    相关文章

      网友评论

          本文标题:GCD之同步异步与串行并行队列详解

          本文链接:https://www.haomeiwen.com/subject/ooaydttx.html