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
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯絡作者獲得授權並註明出處。
相關文章
- 多個網路請求中GCD訊號量的使用GC
- 併發請求的優先順序
- iOS GCD (四) dispatch_semaphore 訊號量iOSGC
- iOS專案開發實戰——使用AFNetworking進行Http Get請求iOSHTTP
- iOS開發·網路請求大總結(NSURLConnection,NSURLSession,AFNetworking)iOSSession
- 多個ajax axios請求,呼叫按照順序執行iOS
- 使用GCD實現和封裝分組併發網路請求GC封裝
- iOS開發之GCDiOSGC
- 玩轉iOS開發:iOS中的GCD開發(一)iOSGC
- 玩轉iOS開發:iOS中的GCD開發(三)iOSGC
- 玩轉iOS開發:iOS中的GCD開發(二)iOSGC
- Semaphore-訊號量的實現分析
- Linux中訊號量的實現Linux
- iOS開發 支援https請求以及https請求的抓包iOSHTTP
- iOS 中的 GCD 實現詳解iOSGC
- Java實現順序表Java
- AFNetworking的請求頭設定(token)
- iOS開發 GET、POST請求方法:NSURLSession篇iOSSession
- 發起GPRS撥號請求
- AFNetworking3.0 HTTPS請求HTTP
- DS順序表--類實現
- 玩轉iOS開發:實戰開發中的GCD Tips小技巧 (二)iOSGC
- 網路請求-手把手實現axiosiOS
- 線性表的使用——順序實現
- React、Axios、MockJs實現Ajax的請求攔截ReactiOSMockJS
- AFNetworking(二)AFNetworking對form-data請求體的處理ORM
- iOS 開發中使用 NSURLProtocol 攔截 HTTP 請求iOSProtocolHTTP
- iOS開發 GET、POST請求方法:NSURLConnection篇iOS
- iOS_對AFNetWorking的請求頭引數進行sha1加密iOS加密
- iOS開發——從網路請求照片的兩種方法iOS
- linux 中實現資料按照指定行號順序輸出Linux
- 【freertos】011-訊號量、互斥量及優先順序繼承機制原始碼分析繼承原始碼
- iOS 同步請求 非同步請求 GET請求 POST請求iOS非同步
- RabbitMQ多消費者順序性消費訊息實現MQ
- Android 擴充套件 OkHttp 支援請求優先順序排程Android套件HTTP
- C語言實現順序表C語言
- PHP實現簡單順序棧PHP
- iOS專案開發實戰——使用SDWebImage庫進行圖片請求iOSWeb