亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 系統 > iOS > 正文

詳解iOS中多線程app開發的GCD隊列的使用

2020-07-26 03:30:32
字體:
來源:轉載
供稿:網友

GCD的基本使用

一、主隊列介紹

主隊列:是和主線程相關聯的隊列,主隊列是GCD自帶的一種特殊的串行隊列,放在主隊列中得任務,都會放到主線程中執行。
提示:如果把任務放到主隊列中進行處理,那么不論處理函數是異步的還是同步的都不會開啟新的線程。
獲取主隊列的方式:

復制代碼 代碼如下:

 dispatch_queue_t queue=dispatch_get_main_queue();

(1)使用異步函數執行主隊列中得任務,代碼示例:

復制代碼 代碼如下:

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

#import "YYViewController.h"

@interface YYViewController ()

@end


復制代碼 代碼如下:

@implementation YYViewController

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

@end


執行效果:

2015122893244602.png (889×87)

(2)使用同步函數,在主線程中執行主隊列中得任務,會發生死循環,任務無法往下執行。示意圖如下:

2015122893319900.png (264×225)

二、基本使用

1.問題 

任務1和任務2是在主線程執行還是子線程執行,還是單獨再開啟一個新的線程?

復制代碼 代碼如下:

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

#import "YYViewController.h"

@interface YYViewController ()

@end


復制代碼 代碼如下:

@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    //開啟一個后臺線程,調用執行test方法
    [self performSelectorInBackground:@selector(test) withObject:nil];
}

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

@end


打印結果:

2015122893339402.png (832×62)

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

復制代碼 代碼如下:

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

#import "YYViewController.h"

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

@end


復制代碼 代碼如下:

@implementation YYViewController

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

//當手指觸摸屏幕的時候,從網絡上下載一張圖片到控制器的view上顯示
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   
    //1.獲取一個全局串行隊列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //2.把任務添加到隊列中執行
    dispatch_async(queue, ^{
       
        //打印當前線程
        NSLog(@"%@",[NSThread currentThread]);
      //3.從網絡上下載圖片
        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


顯示效果:

2015122893357380.png (348×532)

打印結果:

2015122893413566.png (816×65)

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

復制代碼 代碼如下:

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

#import "YYViewController.h"

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

@end


復制代碼 代碼如下:

@implementation YYViewController

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

//當手指觸摸屏幕的時候,從網絡上下載一張圖片到控制器的view上顯示
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
   
    //1.獲取一個全局串行隊列
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //2.把任務添加到隊列中執行
    dispatch_async(queue, ^{
       
        //打印當前線程
        NSLog(@"%@",[NSThread currentThread]);
      //3.從網絡上下載圖片
        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;
            //打印當前線程
            NSLog(@"%@",[NSThread currentThread]);
        });
    });
}

@end


打印結果:

2015122893433477.png (805×75)

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

 

三、線程間通信

從子線程回到主線程

復制代碼 代碼如下:

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

// 回到主線程,執⾏UI刷新操作
});
});


GCD的常見用法
一、延遲執行
1.介紹
iOS常見的延時執行有2種方式
(1)調用NSObject的方法

復制代碼 代碼如下:

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

// 2秒后再調用self的run方法


(2)使用GCD函數
復制代碼 代碼如下:

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

    // 2秒后異步執行這里的代碼...

});

2.說明

第一種方法,該方法在那個線程調用,那么run就在哪個線程執行(當前線程),通常是主線程。

復制代碼 代碼如下:

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

說明:在3秒鐘之后,執行run函數

代碼示例:

復制代碼 代碼如下:

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

#import "YYViewController.h"

@interface YYViewController ()

@end


復制代碼 代碼如下:

@implementation YYViewController

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

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


說明:如果把該方法放在異步函數中執行,則方法不會被調用(BUG?)

2015122893507915.png (874×135)

第二種方法,

復制代碼 代碼如下:

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

       //延遲執行的方法

    });


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

參數說明:

2015122893527935.png (728×207)

什么時間,執行這個隊列中的這個任務。

代碼示例:

復制代碼 代碼如下:

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

#import "YYViewController.h"

@interface YYViewController ()

@end


復制代碼 代碼如下:

@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

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

@end


2015122893549463.png (859×108)

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

如果隊列是主隊列,那么就在主線程執行,如果隊列是并發隊列,那么會新開啟一個線程,在子線程中執行。

 

二、一次性代碼

1.實現一次性代碼

需求:點擊控制器只有第一次點擊的時候才打印。

實現代碼:

復制代碼 代碼如下:

//
//  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(@"該行代碼只執行一次");
        _log=YES;
    }
}
@end


缺點:這是一個對象方法,如果又創建一個新的控制器,那么打印代碼又會執行,因為每個新創建的控制器都有自己的布爾類型,且新創建的默認為NO,因此不能保證改行代碼在整個程序中只打印一次。

2.使用dispatch_once一次性代碼

使用dispatch_once函數能保證某段代碼在程序運行過程中只被執行1次

復制代碼 代碼如下:

static dispatch_once_t onceToken;

dispatch_once(&onceToken, ^{

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

});


整個程序運行過程中,只會執行一次。

代碼示例:

復制代碼 代碼如下:

//
//  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(@"該行代碼只執行一次");
//        _log=YES;
//    }
//}

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


效果(程序運行過程中,打印代碼只會執行一次):

2015122893610032.png (873×96)

三、隊列組

需求:從網絡上下載兩張圖片,把兩張圖片合并成一張最終顯示在view上。

1.第一種方法

代碼示例:

復制代碼 代碼如下:

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

#import "YYViewController.h"
//宏定義全局并發隊列
#define global_quque    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
//宏定義主隊列
#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


復制代碼 代碼如下:

@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //獲取全局并發隊列
//    dispatch_queue_t queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //獲取主隊列
//    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();
            //關閉上下文
            UIGraphicsEndImageContext();
               NSLog(@"圖片合并完成---%@",[NSThread currentThread]);
        });
        //
    });
}

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


顯示效果:

2015122893637424.png (348×532)

打印查看:

2015122893655998.png (845×101)

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

提示:使用隊列組可以讓圖片1和圖片2的下載任務同時進行,且當兩個下載任務都完成的時候回到主線程進行顯示。

2.使用隊列組解決

步驟:

創建一個組

開啟一個任務下載圖片1

 開啟一個任務下載圖片2

同時執行下載圖片1/下載圖片2操作

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

代碼示例

復制代碼 代碼如下:

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

#import "YYViewController.h"
//宏定義全局并發隊列
#define global_quque    dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
//宏定義主隊列
#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


復制代碼 代碼如下:

@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.創建一個隊列組
        dispatch_group_t group = dispatch_group_create();
    
    //2.開啟一個任務下載圖片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.開啟一個任務下載圖片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]);
    });
   
    //同時執行下載圖片1/下載圖片2操作
   
   //4.等group中的所有任務都執行完畢, 再回到主線程執行其他操作
    dispatch_group_notify(group,main_queue, ^{
        NSLog(@"顯示圖片---%@",[NSThread currentThread]);
        self.imageView1.image=image1;
        self.imageView2.image=image2;
       
        //合并兩張圖片
        //注意最后一個參數是浮點數(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();
        //關閉上下文
        UIGraphicsEndImageContext();
       
        NSLog(@"圖片合并完成---%@",[NSThread currentThread]);
    });
   
}
-(void)download2image
{
    //獲取全局并發隊列
//    dispatch_queue_t queue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    //獲取主隊列
//    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();
            //關閉上下文
            UIGraphicsEndImageContext();
               NSLog(@"圖片合并完成---%@",[NSThread currentThread]);
        });
        //
    });
}

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


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

2015122893717839.png (837×92)

2.補充說明

有這么1種需求:

首先:分別異步執行2個耗時的操作

其次:等2個異步操作都執行完畢后,再回到主線程執行操作

 

如果想要快速高效地實現上述需求,可以考慮用隊列組

復制代碼 代碼如下:

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(), ^{

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

});

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲专区国产精品| 国产精品男人爽免费视频1| 91精品在线影院| 久久国产精品久久国产精品| 丝袜美腿亚洲一区二区| 国产在线精品播放| 精品欧美国产一区二区三区| 综合网中文字幕| 久久亚洲精品国产亚洲老地址| 亚洲精品一区二区久| 亚洲欧美日韩一区二区在线| 欧美大人香蕉在线| 日韩免费黄色av| 中文字幕欧美日韩va免费视频| 久久夜色精品亚洲噜噜国产mv| 精品丝袜一区二区三区| 欧美国产高跟鞋裸体秀xxxhd| 国产精品偷伦视频免费观看国产| 一个人www欧美| 亚洲aaaaaa| 久久网福利资源网站| 国产成人久久精品| 成人观看高清在线观看免费| 亚洲有声小说3d| 国产精品夜间视频香蕉| 欧美性生交大片免网| 国产精品一区二区久久久久| 色99之美女主播在线视频| 亚洲全黄一级网站| 久久久久久国产精品久久| 欧美俄罗斯乱妇| 亚洲精品成a人在线观看| xvideos国产精品| 91伊人影院在线播放| 亚洲人成在线播放| 色与欲影视天天看综合网| 欧美成人在线免费| 法国裸体一区二区| 国产91久久婷婷一区二区| 一区二区成人av| 麻豆成人在线看| 国产不卡一区二区在线播放| 欧美综合在线观看| 色七七影院综合| 色偷偷91综合久久噜噜| 国产精品第七影院| 日韩在线观看av| y97精品国产97久久久久久| 亚洲第一精品自拍| 亚洲嫩模很污视频| 成人激情视频网| 国产成人97精品免费看片| 国产精品高潮呻吟视频| 欧美日韩国产中文字幕| 欧美一级在线播放| 国产亚洲欧洲在线| 日本精品视频在线播放| 欧美成人午夜激情视频| 精品亚洲男同gayvideo网站| 欧美大片免费观看在线观看网站推荐| 欧美一区二区三区免费视| 国产精品男人的天堂| 精品久久久久久国产| 日韩av在线精品| 日韩一区二区欧美| 欧美裸体xxxxx| 国产精品黄色影片导航在线观看| 亚洲精品在线91| 中文字幕国产精品久久| 亚洲电影成人av99爱色| 精品久久香蕉国产线看观看gif| 黑人狂躁日本妞一区二区三区| 亚洲精品国产精品国产自| 超薄丝袜一区二区| 日本sm极度另类视频| 黑人巨大精品欧美一区二区| 国产欧美一区二区三区在线看| 欧美午夜精品在线| 亚洲a在线观看| 久久国产精品网站| 日韩在线一区二区三区免费视频| 日韩高清不卡av| 国产亚洲欧美另类中文| 亚洲精品aⅴ中文字幕乱码| 国产精品99一区| 亚洲一区av在线播放| 日本欧美中文字幕| 国产精品丝袜久久久久久不卡| 日韩少妇与小伙激情| 亚洲国产精久久久久久| 91精品国产综合久久男男| 91av在线免费观看视频| 在线亚洲国产精品网| 亚洲高清在线观看| 日韩福利视频在线观看| 久久精品视频中文字幕| 精品国产一区二区三区四区在线观看| 国产精品丝袜久久久久久高清| 亚洲电影在线观看| 亚洲精品福利在线观看| 国产精品都在这里| 国产成人亚洲综合91| 国产69精品99久久久久久宅男| 色综合色综合久久综合频道88| 91久久精品国产| 日韩在线免费高清视频| 久久国产精品99国产精| 国产不卡在线观看| 亚洲大尺度美女在线| 中文字幕亚洲欧美日韩2019| 久久中文字幕在线| 亚洲成在人线av| 日本久久久久久久久| 91av国产在线| 国产精品av电影| 午夜欧美不卡精品aaaaa| 亚洲男女性事视频| 欧美日韩在线另类| 欧美在线激情网| 亚洲精品视频播放| 麻豆精品精华液| 亚洲伊人一本大道中文字幕| 97免费视频在线播放| 亚洲影院色在线观看免费| 国内精品伊人久久| 美女黄色丝袜一区| 亚洲午夜未删减在线观看| 国产成人亚洲精品| 久久精品国产2020观看福利| 欧美激情视频网址| 91久久久在线| 亚洲女人被黑人巨大进入al| 日韩免费视频在线观看| 久久精品91久久香蕉加勒比| 91在线高清视频| 亚洲精品福利视频| 欧美黑人又粗大| zzijzzij亚洲日本成熟少妇| 中文字幕av一区| 国产一区私人高清影院| 国产精品吴梦梦| 欧美一级黄色网| 欧美一级bbbbb性bbbb喷潮片| 欧美日韩亚洲精品内裤| 中日韩午夜理伦电影免费| 亚洲精品成人久久久| 伊人久久久久久久久久久久久| 日本成人免费在线| 一区二区三区视频在线| 国产精品亚洲网站| 91综合免费在线| 国产精品av电影| 日韩高清电影免费观看完整| 国产亚洲欧洲在线| 国产精品com| 亚洲欧美精品一区二区| 亚洲精品www久久久| 国产精品日韩在线播放| 欧美视频第一页| 日韩欧美在线国产| 日韩在线观看免费高清| 91欧美精品午夜性色福利在线| 91美女片黄在线观看游戏| 4438全国亚洲精品在线观看视频|