激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - IOS - 詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用

詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用

2021-01-01 14:40文頂頂 IOS

這篇文章主要介紹了詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用,代碼基于傳統(tǒng)的Objective-C,需要的朋友可以參考下

GCD的基本使用

一、主隊(duì)列介紹

主隊(duì)列:是和主線程相關(guān)聯(lián)的隊(duì)列,主隊(duì)列是GCD自帶的一種特殊的串行隊(duì)列,放在主隊(duì)列中得任務(wù),都會(huì)放到主線程中執(zhí)行。
提示:如果把任務(wù)放到主隊(duì)列中進(jìn)行處理,那么不論處理函數(shù)是異步的還是同步的都不會(huì)開啟新的線程。
獲取主隊(duì)列的方式:

 

復(fù)制代碼 代碼如下:


 dispatch_queue_t queue=dispatch_get_main_queue();

 

(1)使用異步函數(shù)執(zhí)行主隊(duì)列中得任務(wù),代碼示例:

復(fù)制代碼 代碼如下:


//
//  YYViewController.m
//  12-GCD的基本使用(主隊(duì)列)
//
//  Created by 孔醫(yī)己 on 14-6-25.
//  Copyright (c) 2014年 itcast. All rights reserved.
//

#import "YYViewController.h"

@interface YYViewController ()

@end

 

復(fù)制代碼 代碼如下:


@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
   
    //打印主線程
     NSLog(@"打印主線程--%@", [NSThread mainThread]);
    
    //1.獲取主隊(duì)列
    dispatch_queue_t queue=dispatch_get_main_queue();
    //2.把任務(wù)添加到主隊(duì)列中執(zhí)行
    dispatch_async(queue, ^{
        NSLog(@"使用異步函數(shù)執(zhí)行主隊(duì)列中的任務(wù)1--%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"使用異步函數(shù)執(zhí)行主隊(duì)列中的任務(wù)2--%@",[NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"使用異步函數(shù)執(zhí)行主隊(duì)列中的任務(wù)3--%@",[NSThread currentThread]);
    });
}

@end


執(zhí)行效果:

詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用

(2)使用同步函數(shù),在主線程中執(zhí)行主隊(duì)列中得任務(wù),會(huì)發(fā)生死循環(huán),任務(wù)無法往下執(zhí)行。示意圖如下:

詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用

二、基本使用

1.問題 

任務(wù)1和任務(wù)2是在主線程執(zhí)行還是子線程執(zhí)行,還是單獨(dú)再開啟一個(gè)新的線程?

復(fù)制代碼 代碼如下:


//
//  YYViewController.m
//  13-GCD基本使用(問題)
//
//  Created by 孔醫(yī)己 on 14-6-25.
//  Copyright (c) 2014年 itcast. All rights reserved.
//

#import "YYViewController.h"

@interface YYViewController ()

@end

 

復(fù)制代碼 代碼如下:


@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    //開啟一個(gè)后臺(tái)線程,調(diào)用執(zhí)行test方法
    [self performSelectorInBackground:@selector(test) withObject:nil];
}

-(void)test
{
    NSLog(@"當(dāng)前線程---%@",[NSThread currentThread]);
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
   
    //異步函數(shù)
    dispatch_async(queue, ^{
        NSLog(@"任務(wù)1所在的線程----%@",[NSThread currentThread]);
    });
   
    //同步函數(shù)
    dispatch_sync(queue, ^{
        NSLog(@"任務(wù)2所在的線程----%@",[NSThread currentThread]);
    });
}

@end


打印結(jié)果:

詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用

2.開啟子線程,加載圖片

復(fù)制代碼 代碼如下:


//
//  YYViewController.m
//  14-GCD基本使用(下載圖片)
//
//  Created by 孔醫(yī)己 on 14-6-25.
//  Copyright (c) 2014年 itcast. All rights reserved.
//

#import "YYViewController.h"

@interface YYViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end

 

復(fù)制代碼 代碼如下:


@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
   
}

//當(dāng)手指觸摸屏幕的時(shí)候,從網(wǎng)絡(luò)上下載一張圖片到控制器的view上顯示
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   
    //1.獲取一個(gè)全局串行隊(duì)列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //2.把任務(wù)添加到隊(duì)列中執(zhí)行
    dispatch_async(queue, ^{
       
        //打印當(dāng)前線程
        NSLog(@"%@",[NSThread currentThread]);
      //3.從網(wǎng)絡(luò)上下載圖片
        NSURL *urlstr=[NSURL URLWithString:@"http://h.hiphotos.baidu.com/baike/w%3D268/sign=30b3fb747b310a55c424d9f28f444387/1e30e924b899a9018b8d3ab11f950a7b0308f5f9.jpg"];
        NSData *data=[NSData dataWithContentsOfURL:urlstr];
        UIImage *image=[UIImage imageWithData:data];
        //提示
        NSLog(@"圖片加載完畢");
        
        //4.回到主線程,展示圖片
        [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
    });
}

@end


顯示效果:

詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用

打印結(jié)果:

詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用

要求使用GCD的方式,在子線程加載圖片完畢后,主線程拿到加載的image刷新UI界面。

復(fù)制代碼 代碼如下:


//
//  YYViewController.m
//  14-GCD基本使用(下載圖片)
//
//  Created by 孔醫(yī)己 on 14-6-25.
//  Copyright (c) 2014年 itcast. All rights reserved.
//

#import "YYViewController.h"

@interface YYViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;

@end

 

復(fù)制代碼 代碼如下:


@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
   
}

//當(dāng)手指觸摸屏幕的時(shí)候,從網(wǎng)絡(luò)上下載一張圖片到控制器的view上顯示
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   
    //1.獲取一個(gè)全局串行隊(duì)列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //2.把任務(wù)添加到隊(duì)列中執(zhí)行
    dispatch_async(queue, ^{
       
        //打印當(dāng)前線程
        NSLog(@"%@",[NSThread currentThread]);
      //3.從網(wǎng)絡(luò)上下載圖片
        NSURL *urlstr=[NSURL URLWithString:@"http://h.hiphotos.baidu.com/baike/w%3D268/sign=30b3fb747b310a55c424d9f28f444387/1e30e924b899a9018b8d3ab11f950a7b0308f5f9.jpg"];
        NSData *data=[NSData dataWithContentsOfURL:urlstr];
        UIImage *image=[UIImage imageWithData:data];
        //提示
        NSLog(@"圖片加載完畢");
       
        //4.回到主線程,展示圖片
//        [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
        dispatch_async(dispatch_get_main_queue(), ^{
            self.imageView.image=image;
            //打印當(dāng)前線程
            NSLog(@"%@",[NSThread currentThread]);
        });
    });
}

@end


打印結(jié)果:

詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用

好處:子線程中得所有數(shù)據(jù)都可以直接拿到主線程中使用,更加的方便和直觀。

 

三、線程間通信

從子線程回到主線程

復(fù)制代碼 代碼如下:


dispatch_async( dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 執(zhí)?耗時(shí)的異步操作...
dispatch_async(dispatch_get_main_queue(), ^{

// 回到主線程,執(zhí)?UI刷新操作
});
});

 


GCD的常見用法
一、延遲執(zhí)行

1.介紹
iOS常見的延時(shí)執(zhí)行有2種方式
(1)調(diào)用NSObject的方法

復(fù)制代碼 代碼如下:


[self performSelector:@selector(run) withObject:nil afterDelay:2.0];

// 2秒后再調(diào)用self的run方法


(2)使用GCD函數(shù)

復(fù)制代碼 代碼如下:


dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

    // 2秒后異步執(zhí)行這里的代碼...

});

2.說明

第一種方法,該方法在那個(gè)線程調(diào)用,那么run就在哪個(gè)線程執(zhí)行(當(dāng)前線程),通常是主線程。

復(fù)制代碼 代碼如下:

[self performSelector:@selector(run) withObject:nil afterDelay:3.0];


說明:在3秒鐘之后,執(zhí)行run函數(shù)

代碼示例:

復(fù)制代碼 代碼如下:


//
//  YYViewController.m
//  01-GCD的常見使用(延遲執(zhí)行)
//
//  Created by apple on 14-6-25.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"

@interface YYViewController ()

@end

 

復(fù)制代碼 代碼如下:


@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    NSLog(@"打印線程----%@",[NSThread currentThread]);
    //延遲執(zhí)行
    //第一種方法:延遲3秒鐘調(diào)用run函數(shù)
    [self performSelector:@selector(run) withObject:nil afterDelay:2.0];
   
}
-(void)run
{
    NSLog(@"延遲執(zhí)行----%@",[NSThread currentThread]);
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //在異步函數(shù)中執(zhí)行
    dispatch_queue_t queue = dispatch_queue_create("wendingding", 0);
   
    dispatch_sync(queue, ^{
        [self performSelector:@selector(test) withObject:nil afterDelay:1.0];
    });
    NSLog(@"異步函數(shù)");
}
-(void)test
{
    NSLog(@"異步函數(shù)中延遲執(zhí)行----%@",[NSThread currentThread]);
}
@end


說明:如果把該方法放在異步函數(shù)中執(zhí)行,則方法不會(huì)被調(diào)用(BUG?)

詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用

第二種方法,

復(fù)制代碼 代碼如下:


 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

       //延遲執(zhí)行的方法

    });


說明:在5秒鐘之后,執(zhí)行block中的代碼段。

參數(shù)說明:

詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用

什么時(shí)間,執(zhí)行這個(gè)隊(duì)列中的這個(gè)任務(wù)。

代碼示例:

復(fù)制代碼 代碼如下:


//
//  YYViewController.m
//  02-GCD常見使用(延遲執(zhí)行2)
//
//  Created by apple on 14-6-25.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"

@interface YYViewController ()

@end

 

復(fù)制代碼 代碼如下:


@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSLog(@"打印當(dāng)前線程---%@",  [NSThread currentThread]);
    
    //延遲執(zhí)行,第二種方式
     //可以安排其線程(1),主隊(duì)列
     dispatch_queue_t queue= dispatch_get_main_queue();
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC)), queue, ^{
        NSLog(@"主隊(duì)列--延遲執(zhí)行------%@",[NSThread currentThread]);
    });
   
    //可以安排其線程(2),并發(fā)隊(duì)列
    //1.獲取全局并發(fā)隊(duì)列
    dispatch_queue_t queue1= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //2.計(jì)算任務(wù)執(zhí)行的時(shí)間
    dispatch_time_t when=dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0 * NSEC_PER_SEC));
    //3.會(huì)在when這個(gè)時(shí)間點(diǎn),執(zhí)行queue中的這個(gè)任務(wù)
    dispatch_after(when, queue1, ^{
        NSLog(@"并發(fā)隊(duì)列-延遲執(zhí)行------%@",[NSThread currentThread]);
    });
}

@end

 

詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用

延遲執(zhí)行:不需要再寫方法,且它還傳遞了一個(gè)隊(duì)列,我們可以指定并安排其線程。

如果隊(duì)列是主隊(duì)列,那么就在主線程執(zhí)行,如果隊(duì)列是并發(fā)隊(duì)列,那么會(huì)新開啟一個(gè)線程,在子線程中執(zhí)行。

 

二、一次性代碼

1.實(shí)現(xiàn)一次性代碼

需求:點(diǎn)擊控制器只有第一次點(diǎn)擊的時(shí)候才打印。

實(shí)現(xiàn)代碼:

復(fù)制代碼 代碼如下:


//
//  YYViewController.m
//  03-GCD常見使用(一次性代碼)
//
//  Created by apple on 14-6-25.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"

@interface YYViewController ()
@property(nonatomic,assign) BOOL log;
@end

@implementation YYViewController

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    if (_log==NO) {
        NSLog(@"該行代碼只執(zhí)行一次");
        _log=YES;
    }
}
@end


缺點(diǎn):這是一個(gè)對(duì)象方法,如果又創(chuàng)建一個(gè)新的控制器,那么打印代碼又會(huì)執(zhí)行,因?yàn)槊總€(gè)新創(chuàng)建的控制器都有自己的布爾類型,且新創(chuàng)建的默認(rèn)為NO,因此不能保證改行代碼在整個(gè)程序中只打印一次。

2.使用dispatch_once一次性代碼

使用dispatch_once函數(shù)能保證某段代碼在程序運(yùn)行過程中只被執(zhí)行1次

復(fù)制代碼 代碼如下:


static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

    // 只執(zhí)行1次的代碼(這里面默認(rèn)是線程安全的)

});


整個(gè)程序運(yùn)行過程中,只會(huì)執(zhí)行一次。

代碼示例:

復(fù)制代碼 代碼如下:


//
//  YYViewController.m
//  03-GCD常見使用(一次性代碼)
//
//  Created by apple on 14-6-25.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"

@interface YYViewController ()
@property(nonatomic,assign) BOOL log;
@end

 

復(fù)制代碼 代碼如下:


@implementation YYViewController

//-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
//{
//    if (_log==NO) {
//        NSLog(@"該行代碼只執(zhí)行一次");
//        _log=YES;
//    }
//}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        NSLog(@"該行代碼只執(zhí)行一次");
    });
}
@end


效果(程序運(yùn)行過程中,打印代碼只會(huì)執(zhí)行一次):

詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用

三、隊(duì)列組

需求:從網(wǎng)絡(luò)上下載兩張圖片,把兩張圖片合并成一張最終顯示在view上。

1.第一種方法

代碼示例:

復(fù)制代碼 代碼如下:


//
//  YYViewController.m
//  04-GCD基本使用(隊(duì)列組下載圖片)
//
//  Created by apple on 14-6-25.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"
//宏定義全局并發(fā)隊(duì)列
#define global_quque    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
//宏定義主隊(duì)列
#define main_queue       dispatch_get_main_queue()

@interface YYViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView1;
@property (weak, nonatomic) IBOutlet UIImageView *imageView2;
@property (weak, nonatomic) IBOutlet UIImageView *imageView3;

@end

 

復(fù)制代碼 代碼如下:


@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //獲取全局并發(fā)隊(duì)列
//    dispatch_queue_t queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //獲取主隊(duì)列
//    dispatch_queue_t queue= dispatch_get_main_queue();
   
//    圖片1:http://d.hiphotos.baidu.com/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=2b9a12172df5e0fefa1581533d095fcd/cefc1e178a82b9019115de3d738da9773912ef00.jpg
//    圖片2:http://h.hiphotos.baidu.com/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=f47fd63ca41ea8d39e2f7c56f6635b2b/1e30e924b899a9018b8d3ab11f950a7b0308f5f9.jpg
    dispatch_async(global_quque, ^{
        //下載圖片1
       UIImage *image1= [self imageWithUrl:@"http://d.hiphotos.baidu.com/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=2b9a12172df5e0fefa1581533d095fcd/cefc1e178a82b9019115de3d738da9773912ef00.jpg"];
        NSLog(@"圖片1下載完成---%@",[NSThread currentThread]);
   
        //下載圖片2
       UIImage *image2= [self imageWithUrl:@"http://h.hiphotos.baidu.com/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=f47fd63ca41ea8d39e2f7c56f6635b2b/1e30e924b899a9018b8d3ab11f950a7b0308f5f9.jpg"];
        NSLog(@"圖片2下載完成---%@",[NSThread currentThread]);
       
        //回到主線程顯示圖片
        dispatch_async(main_queue, ^{
             NSLog(@"顯示圖片---%@",[NSThread currentThread]);
            self.imageView1.image=image1;
            self.imageView2.image=image2;
            //合并兩張圖片
            UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 100), NO, 0.0);
            [image1 drawInRect:CGRectMake(0, 0, 100, 100)];
            [image2 drawInRect:CGRectMake(100, 0, 100, 100)];
            self.imageView3.image=UIGraphicsGetImageFromCurrentImageContext();
            //關(guān)閉上下文
            UIGraphicsEndImageContext();
               NSLog(@"圖片合并完成---%@",[NSThread currentThread]);
        });
        //
    });
}

//封裝一個(gè)方法,傳入一個(gè)url參數(shù),返回一張網(wǎng)絡(luò)上下載的圖片
-(UIImage *)imageWithUrl:(NSString *)urlStr
{
    NSURL *url=[NSURL URLWithString:urlStr];
    NSData *data=[NSData dataWithContentsOfURL:url];
    UIImage *image=[UIImage imageWithData:data];
    return image;
}
@end


顯示效果:

詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用

打印查看:

詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用

問題:這種方式的效率不高,需要等到圖片1.圖片2都下載完成后才行。

提示:使用隊(duì)列組可以讓圖片1和圖片2的下載任務(wù)同時(shí)進(jìn)行,且當(dāng)兩個(gè)下載任務(wù)都完成的時(shí)候回到主線程進(jìn)行顯示。

2.使用隊(duì)列組解決

步驟:

創(chuàng)建一個(gè)組

開啟一個(gè)任務(wù)下載圖片1

 開啟一個(gè)任務(wù)下載圖片2

同時(shí)執(zhí)行下載圖片1\下載圖片2操作

等group中的所有任務(wù)都執(zhí)行完畢, 再回到主線程執(zhí)行其他操作

代碼示例

復(fù)制代碼 代碼如下:


//
//  YYViewController.m
//  04-GCD基本使用(隊(duì)列組下載圖片)
//
//  Created by apple on 14-6-25.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"
//宏定義全局并發(fā)隊(duì)列
#define global_quque    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
//宏定義主隊(duì)列
#define main_queue       dispatch_get_main_queue()

@interface YYViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView1;
@property (weak, nonatomic) IBOutlet UIImageView *imageView2;
@property (weak, nonatomic) IBOutlet UIImageView *imageView3;

@end

 

復(fù)制代碼 代碼如下:


@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //    圖片1:http://d.hiphotos.baidu.com/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=2b9a12172df5e0fefa1581533d095fcd/cefc1e178a82b9019115de3d738da9773912ef00.jpg
    //    圖片2:http://h.hiphotos.baidu.com/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=f47fd63ca41ea8d39e2f7c56f6635b2b/1e30e924b899a9018b8d3ab11f950a7b0308f5f9.jpg
   
   
    //1.創(chuàng)建一個(gè)隊(duì)列組
        dispatch_group_t group = dispatch_group_create();
    
    //2.開啟一個(gè)任務(wù)下載圖片1
    __block UIImage *image1=nil;
    dispatch_group_async(group, global_quque, ^{
        image1= [self imageWithUrl:@"http://d.hiphotos.baidu.com/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=2b9a12172df5e0fefa1581533d095fcd/cefc1e178a82b9019115de3d738da9773912ef00.jpg"];
        NSLog(@"圖片1下載完成---%@",[NSThread currentThread]);
    });
   
    //3.開啟一個(gè)任務(wù)下載圖片2
    __block UIImage *image2=nil;
    dispatch_group_async(group, global_quque, ^{
        image2= [self imageWithUrl:@"http://h.hiphotos.baidu.com/baike/c0%3Dbaike80%2C5%2C5%2C80%2C26/sign=f47fd63ca41ea8d39e2f7c56f6635b2b/1e30e924b899a9018b8d3ab11f950a7b0308f5f9.jpg"];
        NSLog(@"圖片2下載完成---%@",[NSThread currentThread]);
    });
   
    //同時(shí)執(zhí)行下載圖片1\下載圖片2操作
   
   //4.等group中的所有任務(wù)都執(zhí)行完畢, 再回到主線程執(zhí)行其他操作
    dispatch_group_notify(group,main_queue, ^{
        NSLog(@"顯示圖片---%@",[NSThread currentThread]);
        self.imageView1.image=image1;
        self.imageView2.image=image2;
       
        //合并兩張圖片
        //注意最后一個(gè)參數(shù)是浮點(diǎn)數(shù)(0.0),不要寫成0。
        UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 100), NO, 0.0);
        [image1 drawInRect:CGRectMake(0, 0, 100, 100)];
        [image2 drawInRect:CGRectMake(100, 0, 100, 100)];
        self.imageView3.image=UIGraphicsGetImageFromCurrentImageContext();
        //關(guān)閉上下文
        UIGraphicsEndImageContext();
       
        NSLog(@"圖片合并完成---%@",[NSThread currentThread]);
    });
   
}
-(void)download2image
{
    //獲取全局并發(fā)隊(duì)列
//    dispatch_queue_t queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //獲取主隊(duì)列
//    dispatch_queue_t queue= dispatch_get_main_queue();
   
    dispatch_async(global_quque, ^{
        //下載圖片1
       UIImage *image1= [self imageWithUrl:@"http://news.baidu.com/z/resource/r/image/2014-06-22/2a1009253cf9fc7c97893a4f0fe3a7b1.jpg"];
        NSLog(@"圖片1下載完成---%@",[NSThread currentThread]);
   
        //下載圖片2
       UIImage *image2= [self imageWithUrl:@"http://news.baidu.com/z/resource/r/image/2014-06-22/2a1009253cf9fc7c97893a4f0fe3a7b1.jpg"];
        NSLog(@"圖片2下載完成---%@",[NSThread currentThread]);
       
        //回到主線程顯示圖片
        dispatch_async(main_queue, ^{
             NSLog(@"顯示圖片---%@",[NSThread currentThread]);
            self.imageView1.image=image1;
            self.imageView2.image=image2;
            //合并兩張圖片
            UIGraphicsBeginImageContextWithOptions(CGSizeMake(200, 100), NO, 0.0);
            [image1 drawInRect:CGRectMake(0, 0, 100, 100)];
            [image2 drawInRect:CGRectMake(0, 0, 100, 100)];
            self.imageView3.image=UIGraphicsGetImageFromCurrentImageContext();
            //關(guān)閉上下文
            UIGraphicsEndImageContext();
               NSLog(@"圖片合并完成---%@",[NSThread currentThread]);
        });
        //
    });
}

//封裝一個(gè)方法,傳入一個(gè)url參數(shù),返回一張網(wǎng)絡(luò)上下載的圖片
-(UIImage *)imageWithUrl:(NSString *)urlStr
{
    NSURL *url=[NSURL URLWithString:urlStr];
    NSData *data=[NSData dataWithContentsOfURL:url];
    UIImage *image=[UIImage imageWithData:data];
    return image;
}
@end


打印查看(同時(shí)開啟了兩個(gè)子線程,分別下載圖片):

詳解iOS中多線程app開發(fā)的GCD隊(duì)列的使用

2.補(bǔ)充說明

有這么1種需求:

首先:分別異步執(zhí)行2個(gè)耗時(shí)的操作

其次:等2個(gè)異步操作都執(zhí)行完畢后,再回到主線程執(zhí)行操作

 

如果想要快速高效地實(shí)現(xiàn)上述需求,可以考慮用隊(duì)列組

復(fù)制代碼 代碼如下:


dispatch_group_t group =  dispatch_group_create();

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // 執(zhí)行1個(gè)耗時(shí)的異步操作

});

dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    // 執(zhí)行1個(gè)耗時(shí)的異步操作

});

dispatch_group_notify(group, dispatch_get_main_queue(), ^{

    // 等前面的異步操作都執(zhí)行完畢后,回到主線程...

});

 

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本娇小18xxxⅹhd | 成人mm视频在线观看 | 久久蜜臀一区二区三区av | 国产资源在线免费观看 | 中文字幕欧美专区 | 最新中文字幕免费视频 | 久久久久久久久久网 | 久久影院yy6080 | 久久国产精品一区 | 成人免费午夜视频 | 一区二区三区精品国产 | 黄色片网站免费在线观看 | 欧美性黄 | 亚洲免费观看视频 | www.99re14.com | 欧美爱爱一区二区 | 午夜视频福利 | 黄色免费网站在线播放 | 91成| 91丨九色丨国产在线观看 | 日韩精品羞羞答答 | 欧美日韩中文字幕在线 | 欧美日韩a∨毛片一区 | 在线播放亚洲 | 国产精品视频海角社区88 | 欧美一区2区三区4区公司二百 | 91高清完整版在线观看 | 日本免费不卡一区二区 | 久久亚洲网 | 久久久久中精品中文字幕19 | 国产免费人做人爱午夜视频 | 国产精品一区二区三区在线看 | 免费国产 | 亚洲一区在线看 | 成人福利在线免费观看 | 欧美a视频在线观看 | 成人一级视频在线观看 | 亚洲天堂欧美在线 | 欧美一级免费在线观看 | 成人午夜在线播放 | 精品国产乱码久久久久久久久 |