- 線程通訊
//獲取全局隊列
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
//封裝任務(wù),將任務(wù)添加到隊列中
dispatch_async(queue, ^{
NSLog(@"執(zhí)行任務(wù)%@",[NSThread currentThread]);
//回到主線程刷新任務(wù)
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"刷新UI%@",[NSThread currentThread]);
});
});
//異步函數(shù)并不需要馬上執(zhí)行任務(wù),不會阻塞線程。(先執(zhí)行NSLog后再回頭執(zhí)行block里的任物)
NSLog(@"異步多線程");
- 一次性代碼
//整個程序運行過程中,只會執(zhí)行一次,開發(fā)實用場景:單例
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"一次性代碼");
});
- 延遲執(zhí)行
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), queue, ^{
NSLog(@"延遲執(zhí)行%@",[NSThread currentThread]);
});
NSLog(@"異步多線程");
- 柵欄函數(shù)
//注意:柵欄函數(shù)不能使用全局并發(fā)隊列
dispatch_queue_t queue = dispatch_queue_create("download", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
NSLog(@"任務(wù)一-%@",[NSThread currentThread]);
});
dispatch_async(queue, ^{
NSLog(@"任務(wù)二-%@",[NSThread currentThread]);
});
//柵欄函數(shù)
//柵欄函數(shù)之前隊列中的任務(wù)執(zhí)行完畢之后才會執(zhí)行,柵欄函數(shù)之后之隊列中的任務(wù)),但不阻塞線程是異步的
dispatch_barrier_async(queue, ^{
NSLog(@"我是柵欄函數(shù)");
});
NSLog(@"異步函數(shù)1");
dispatch_async(queue, ^{
NSLog(@"任務(wù)三-%@",[NSThread currentThread]);
});
NSLog(@"異步函數(shù)2");
```
- 隊列組
```
//1.封裝任務(wù),將任務(wù)添加隊列中,監(jiān)聽隊列的執(zhí)行情況
dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
dispatch_group_t group= dispatch_group_create();
//下載圖片一
dispatch_group_async(group, queue, ^{
NSURL *url=[NSURL URLWithString:@"http://xo7788.com/uploads/allimg/160727/1130119505_0.jpg"];
NSData *imageData=[NSData dataWithContentsOfURL:url];
self.image1=[UIImage imageWithData:imageData];
//下載圖片二
dispatch_group_async(group, queue, ^{
NSURL *url=[NSURL URLWithString:@"http://pic.58pic.com/58pic/17/41/38/88658PICNuP_1024.jpg"];
NSData *imageData=[NSData dataWithContentsOfURL:url];
self.image2=[UIImage imageWithData:imageData];
});
//下載圖片三
dispatch_group_async(group, queue, ^{
NSURL *url=[NSURL URLWithString:@"http://pic.58pic.com/58pic/17/41/38/88658PICNuP_1024.jpg"];
NSData *imageData=[NSData dataWithContentsOfURL:url];
self.image2=[UIImage imageWithData:imageData];
});
//合并圖片
//攔截通知,當(dāng)隊列組的所有任務(wù)完全,執(zhí)行完后會進入下面的方法
//該方法本身是異步的
dispatch_group_notify(group, queue, ^{
//3.1 創(chuàng)建圖形上下文
UIGraphicsBeginImageContext(CGSizeMake(200, 200));
//3.2 畫圖1
[self.image1 drawInRect:CGRectMake(0, 0, 200, 100)];
self.image1 = nil;
//3.3 畫圖2
[self.image2 drawInRect:CGRectMake(0, 100, 200, 100)];
self.image2 = nil;
//3.4 根據(jù)上下文得到一張圖片
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
//3.5 關(guān)閉上下文
UIGraphicsEndImageContext();
NSLog(@"%@合并",[NSThread currentThread]);
dispatch_async(dispatch_get_main_queue(), ^{
self.imageview.image=image;
});
});
NSLog(@"異步函數(shù)");
```
- 多網(wǎng)絡(luò)請求 (GCD信號量)
參考學(xué)習(xí)文章:http://www.itdecent.cn/p/c194ca08776c
開發(fā)需求01:一個很常見的需求:項目中的業(yè)務(wù)接口請求的時候需要Token驗證。我們最簡化這個需求就是:兩個請求,請求1成功返回所需參數(shù)之后,才能開始請求2。
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
//創(chuàng)建一個并行隊列
dispatch_queue_t queque = dispatch_queue_create("GoyakodCreated", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queque, ^{
[self request1];
[self request2];
});
//注意這是請求不能放在主線程上,要不然,AFN的block回掉回造成線程死鎖
}
-
(void)request1{
//01創(chuàng)建信號量并設(shè)置計數(shù)默認為0
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
//1.創(chuàng)建會話管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];//注意:如果返回的是xml數(shù)據(jù),那么應(yīng)該修改AFN的解析方案AFXMLParserResponseSerializer
//注意:如果返回的數(shù)據(jù)既不是xml也不是json那么應(yīng)該修改解析方案為:
//manager.responseSerializer = [AFXMLParserResponseSerializer serializer];//告訴AFN能夠接受text/html類型的數(shù)據(jù)
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];manager.responseSerializer = [AFHTTPResponseSerializer serializer];
//2.發(fā)送GET請求
[manager GET:@"http://www.baidu.com" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task,id _Nullable responseObject) {//02發(fā)送信號量計數(shù)+1 dispatch_semaphore_signal(sema); NSLog(@"網(wǎng)絡(luò)請求1"); //UIImage *image = [UIImage imageWithData:responseObject]; NSLog(@"block-%@",[NSThread currentThread]);} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
dispatch_semaphore_signal(sema);
NSLog(@"請求失敗--%@",error);
}];//若計數(shù)為0則一直等待
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
}
-
(void)request2{
//1.創(chuàng)建會話管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //注意:如果返回的是xml數(shù)據(jù),那么應(yīng)該修改AFN的解析方案AFXMLParserResponseSerializer //注意:如果返回的數(shù)據(jù)既不是xml也不是json那么應(yīng)該修改解析方案為: //manager.responseSerializer = [AFXMLParserResponseSerializer serializer]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //2.發(fā)送GET請求 [manager GET:@"http://120.25.226.186:32812/resources/images/minion_01.png" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task,id _Nullable responseObject) { NSLog(@"網(wǎng)絡(luò)請求2"); //UIImage *image = [UIImage imageWithData:responseObject]; } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { }];}
開發(fā)需求02:兩個網(wǎng)絡(luò)請求后刷新界面
-
(void)viewDidLoad {
[super viewDidLoad];
// 創(chuàng)建信號量
semaphore = dispatch_semaphore_create(0);
// 創(chuàng)建全局并行
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
// 請求一
[self request1];
NSLog(@"1");
});
dispatch_group_async(group, queue, ^{NSLog(@"2"); // 請求二 [self request2];});
dispatch_group_notify(group, queue, ^{
// 2個請求對應(yīng)2次信號等待
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"刷新界面");
});
}
-
(void)request1{
//1.創(chuàng)建會話管理者
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];//注意:如果返回的是xml數(shù)據(jù),那么應(yīng)該修改AFN的解析方案AFXMLParserResponseSerializer
//注意:如果返回的數(shù)據(jù)既不是xml也不是json那么應(yīng)該修改解析方案為:
//manager.responseSerializer = [AFXMLParserResponseSerializer serializer];//告訴AFN能夠接受text/html類型的數(shù)據(jù)
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/html"];manager.responseSerializer = [AFHTTPResponseSerializer serializer];
//2.發(fā)送GET請求
[manager GET:@"http://www.baidu.com" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task,id _Nullable responseObject) {//02發(fā)送信號量計數(shù)+1 dispatch_semaphore_signal(semaphore); NSLog(@"網(wǎng)絡(luò)請求1"); //UIImage *image = [UIImage imageWithData:responseObject]; NSLog(@"block-%@",[NSThread currentThread]);} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
dispatch_semaphore_signal(semaphore);
NSLog(@"請求失敗--%@",error);
}];
}
-
(void)request2{
//1.創(chuàng)建會話管理者 AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; //注意:如果返回的是xml數(shù)據(jù),那么應(yīng)該修改AFN的解析方案AFXMLParserResponseSerializer //注意:如果返回的數(shù)據(jù)既不是xml也不是json那么應(yīng)該修改解析方案為: //manager.responseSerializer = [AFXMLParserResponseSerializer serializer]; manager.responseSerializer = [AFHTTPResponseSerializer serializer]; //2.發(fā)送GET請求 [manager GET:@"http://120.25.226.186:32812/resources/images/minion_01.png" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task,id _Nullable responseObject) { NSLog(@"網(wǎng)絡(luò)請求2"); dispatch_semaphore_signal(semaphore); //UIImage *image = [UIImage imageWithData:responseObject]; } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { dispatch_semaphore_signal(semaphore); }];}