iOS開發 GCD訊號量實現AFNetworking的順序請求
[圖片上傳失敗...(image-97ada5-1545274514848)]
最近遇到一個☝️問題。一個頁面有多個介面,需要請求完介面後,在把介面資料組裝排序後再展示。於是我第一反應是使用GCD_group
或者barrier
.經過實踐失敗了。最後經過多方調研,使用dispatch_semaphore
解決了這個問題,但是也有遇到坑。。。
首先貼出解決方案#1
// /建立訊號量為0
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
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, ^{
[ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/journalismApi" param:nil success:^(id data) {
// 訊號量?+1
dispatch_semaphore_signal(semaphore);
NSLog(@"1請求成功");
} failure:^(NSInteger resultId, NSString *errorMsg) {
// 訊號量?+1
dispatch_semaphore_signal(semaphore);
}];
});
dispatch_group_async(group, queue, ^{
[ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/satinApi?type=1&page=1" param:nil success:^(id data) {
// 訊號量?+1
dispatch_semaphore_signal(semaphore);
NSLog(@"2請求成功");
} failure:^(NSInteger resultId, NSString *errorMsg) {
// 訊號量?+1
dispatch_semaphore_signal(semaphore);
}];
});
dispatch_group_notify(group, queue, ^{
// 訊號量 -1 為0時wait會阻塞執行緒
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"訊號量為0");
[ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/satinCommentApi?id=27610708&page=1" param:nil success:^(id data) {
NSLog(@"3請求成功");
} failure:^(NSInteger resultId, NSString *errorMsg) {
}];
});
列印結果1或2請求結束後才會請求3
2018-09-03 21:49:47.309334+0800 訊號量[20350:707280] 2請求成功
2018-09-03 21:49:48.299139+0800 訊號量[20350:707280] 1請求成功
2018-09-03 21:49:48.299139+0800 訊號量[20350:707371] 訊號量為0
2018-09-03 21:49:48.640118+0800 訊號量[20350:707280] 3請求成功
#2
dispatch_queue_t queue = dispatch_queue_create("ben", NULL);
dispatch_async(queue, ^{
NSLog(@"current1:%@",[NSThread currentThread]);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/journalismApi" param:nil success:^(id data) {
dispatch_semaphore_signal(semaphore);
NSLog(@"1請求成功");
} failure:^(NSInteger resultId, NSString *errorMsg) {
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); //等待訊號,當訊號總量少於0 的時候就會一直等待 ,否則就可以正常的執行,並讓訊號總量-1
[ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/satinApi?type=1&page=1" param:nil success:^(id data) {
dispatch_semaphore_signal(semaphore);
NSLog(@"2請求成功");
} failure:^(NSInteger resultId, NSString *errorMsg) {
dispatch_semaphore_signal(semaphore);
}];
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); //等待訊號,當訊號總量少於0 的時候就會一直等待 ,否則就可以正常的執行,並讓訊號總量-1
[ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/satinCommentApi?id=27610708&page=1" param:nil success:^(id data) {
NSLog(@"3請求成功");
} failure:^(NSInteger resultId, NSString *errorMsg) {
}];
});
列印結果順序執行1,2,3
2018-09-03 21:52:34.881525+0800 訊號量[20448:711755] 1請求成功
2018-09-03 21:52:35.659227+0800 訊號量[20448:711755] 2請求成功
2018-09-03 21:52:35.951249+0800 訊號量[20448:711755] 3請求成功
遇到的坑
NSLog(@"current1:%@",[NSThread currentThread]);
dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
[ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/satinApi?type=1&page=1" param:nil success:^(id data) {
dispatch_semaphore_signal(semaphore);
NSLog(@"2請求成功");
} failure:^(NSInteger resultId, NSString *errorMsg) {
dispatch_semaphore_signal(semaphore);
}];
NSLog(@"你會來這兒嗎1");
NSLog(@"current1:%@",[NSThread currentThread]);
// #######阻塞了主執行緒
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); //等待訊號,當訊號總量少於0 的時候就會一直等待 ,否則就可以正常的執行,並讓訊號總量-1
NSLog(@"你會來這兒嗎2");
[ATBaseRequest getRequestWithMethod:@"https://www.apiopen.top/satinCommentApi?id=27610708&page=1" param:nil success:^(id data) {
NSLog(@"3請求成功");
} failure:^(NSInteger resultId, NSString *errorMsg) {
}];
列印你會發現卡在了NSLog(@"你會來這兒嗎1"); 這裡
原因:阻塞了主執行緒。
2018-09-03 21:56:36.863662+0800 訊號量[20583:717991] current1:<NSThread: 0x604000076680>{number = 1, name = main}
2018-09-03 21:56:36.961266+0800 訊號量[20583:717991] 你會來這兒嗎1
2018-09-03 21:56:36.961413+0800 訊號量[20583:717991] current1:<NSThread: 0x604000076680>{number = 1, name = main}
參考部落格iOS開發 多執行緒的高階應用(一)
demo傳送門:GitHub
作者:本本的開心牧場
連結:https://www.jianshu.com/p/72843289ad5d
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。
相關文章
- iOS開發·網路請求大總結(NSURLConnection,NSURLSession,AFNetworking)iOSSession
- 利用訊號量實現執行緒順序執行執行緒
- iOS GCD (四) dispatch_semaphore 訊號量iOSGC
- AFNetworking(二)AFNetworking對form-data請求體的處理ORM
- iOS 中的 GCD 實現詳解iOSGC
- 順序表的實現
- 順序棧的實現方式
- iOS使用GCD實現一個TimeriOSGC
- 多個ajax axios請求,呼叫按照順序執行iOS
- Linux中訊號量的實現Linux
- Java實現順序表Java
- Semaphore-訊號量的實現分析
- linux 中實現資料按照指定行號順序輸出Linux
- iOS多執行緒開發—GCD (一)iOS執行緒GC
- iOS 開發中使用 NSURLProtocol 攔截 HTTP 請求iOSProtocolHTTP
- DS順序表--類實現
- 線性表的使用——順序實現
- 【freertos】011-訊號量、互斥量及優先順序繼承機制原始碼分析繼承原始碼
- AFNetworking(一)從一次請求瞭解AFHTTPSessionManagerHTTPSession
- 順序賦值的方式實現流水燈賦值
- 【apple id】最新iOS開發者賬號申請流程APPiOS
- iOS GCD執行緒之間的通訊iOSGC執行緒
- RabbitMQ多消費者順序性消費訊息實現MQ
- 順序表實現二分排序排序
- JS實現序列請求JS
- Java實現Http請求JavaHTTP
- 資料結構實驗一:順序表的建立與操作實現、順序表實現約瑟夫環問題資料結構
- [20210218]bash echo 建立順序號.txt
- postman發請求前實現的操作Pre-request ScriptPostman
- 關於RocketMQ的順序訊息MQ
- 順序表的基本方法實現C語言版C語言
- 順序審批流的簡單程式碼實現
- 用whistle實現Abort請求
- KKB : Jquery實現Ajax請求jQuery
- 騰訊雲:免費SSL證書實現https請求HTTP
- 實驗二:順序表的基本操作實現及其應用
- iOS GCD入門和GCD對CPU多核的使用iOSGC
- 前端不會這個就別想著還房貸了?論怎麼讓非同步請求按請求順序返回前端非同步