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

2016-06-13  本文已影响0人  Ariest

同步只能在当前线程中执行任务,不具备开启新线程的能力。异步可以在新线程中执行任务,具备开启新线程的能力。
多线程:一个进程可以开启多条线程,每条线程可以执行不同的任务。实质上在同一时间,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;
            
        });
        
    });

}

上一篇下一篇

猜你喜欢

热点阅读