iOS 通過新增執行緒依賴和訊號量結合實現一個複雜介面請求多個介面時按指定順序執行
阿新 • • 發佈:2019-02-11
前言:本文通過作者的一種思想實現關於iOS中一個介面請求多條資料時,需要按指定順序執行
主要思路:為了實現多個請求介面按指定順序前後執行,本文主要通過新增執行緒依賴關係和GCD的訊號量相結合來實現基本需求貼上Demo地址,感覺可以的麻煩記得點個星星。
直接上程式碼
執行緒依賴關係通過使用系統對GCD的進一步封裝的類NSBlockOperation來實現
-(void)dispatchAllRequest{
// 利用執行緒依賴關係測試
__weak typeof (self)weakSelf =self;
NSBlockOperation * operation1 = [NSBlockOperation blockOperationWithBlock:^{
[weakSelf requestA];
}];
NSBlockOperation * operation2 = [NSBlockOperation blockOperationWithBlock:^{
[weakSelf requestB];
}];
NSBlockOperation * operation3 = [NSBlockOperation blockOperationWithBlock:^{
[weakSelf requestC];
}];
[operation2 addDependency:operation1];
[operation3 addDependency:operation2];
NSOperationQueue * queue = [[NSOperationQueue alloc]init];
[queue addOperations:@[operation1,operation2,operation3] waitUntilFinished:NO ];
}
請求方法的話使用GCD的訊號量來實現阻塞執行緒來達到我們執行緒同步請求的目的
第一個請求資料方法
-(void)requestA{
//建立訊號量並設定計數預設為0
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];;
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.responseSerializer .acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",nil];
[manager GET:@"http://qr.bookln.cn/qr.html?crcode=110000000F00000000000000B3ZX1CEC" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
dispatch_semaphore_signal(sema);
NSLog (@"正在執行A");
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
////計數+1操作
dispatch_semaphore_signal(sema);
NSLog(@"執行錯誤A");
}];
NSLog(@"正在重新整理A");
//若計數為0則一直等待
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
NSLog(@"已經重新整理A");
}
第二個請求資料方法
-(void)requestB{
//建立訊號量並設定計數預設為0
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];;
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",nil];
[manager GET:@"http://qr.bookln.cn/qr.html?crcode=110000000F00000000000000B3ZX1CEC" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
dispatch_semaphore_signal(sema);
NSLog(@"正在執行B");
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
////計數+1操作
dispatch_semaphore_signal(sema);
NSLog(@"執行錯誤B");
}];
NSLog(@"正在重新整理B");
//若計數為0則一直等待
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
NSLog(@"已經重新整理B");
}
第三個請求資料方法
-(void)requestC{
//建立訊號量並設定計數預設為0
dispatch_semaphore_t sema = dispatch_semaphore_create(0);
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];;
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",nil];
[manager GET:@"http://qr.bookln.cn/qr.html?crcode=110000000F00000000000000B3ZX1CEC" parameters:nil progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
dispatch_semaphore_signal(sema);
NSLog(@"正在執行C");
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
////計數+1操作
dispatch_semaphore_signal(sema);
NSLog(@"執行錯誤C");
}];
NSLog(@"正在重新整理C");
//若計數為0則一直等待
dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
NSLog(@"已經重新整理C");
}
為了模擬現實專案中的請求過程,所以用到了請求介面三方AFNetworking
更加貼近真實效果,親測對於一個介面多個介面請求資料需要同步請求的是可用的。
最後附上GCD的訊號量的一些小知識
關於訊號量
訊號量:就是一種可用來控制訪問資源的數量的標識,設定了一個訊號量,線上程訪問之前,加上訊號量的處理,則可告知系統按照我們指定的訊號量數量來執行多個執行緒。
其實,這有點類似鎖機制了,只不過訊號量都是系統幫助我們處理了,我們只需要在執行執行緒之前,設定一個訊號量值,並且在使用時,加上訊號量處理方法就行了。
訊號量為0則阻塞執行緒,大於0則不會阻塞。因此我們可以通過改變訊號量的值,來控制是否阻塞執行緒,從而達到執行緒同步。
在GCD中有三個函式是semaphore的操作,分別是:
dispatch_semaphore_create 建立一個semaphore
dispatch_semaphore_signal 傳送一個訊號
dispatch_semaphore_wait 等待訊號
簡單的介紹一下這三個函式,第一個函式有一個整形的引數,我們可以理解為訊號的總量,dispatch_semaphore_signal是傳送一個訊號,自然會讓訊號總量加1,dispatch_semaphore_wait等待訊號,當訊號總量少於0的時候就會一直等待,否則就可以正常的執行,並讓訊號總量-1,根據這樣的原理,我們便可以快速的建立一個併發控制來同步任務和有限資源訪問控制。
關於NSOperationQueue
建立佇列的兩種方式
1.主佇列
凡是新增到主佇列的任務(NSOperation),都會放在主執行緒執行
NSOperationQueue *queue = [NSOperationQueue mainQueue];
2.其他佇列(非主佇列)
新增到這種佇列的任務(NSOperation),就會自動放到子現場中執行
同時包含了:串形,併發功能
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
以下是系統API提供的新增任務到佇列中的方式
- (void)addOperation:(NSOperation *)op;
- (void)addOperations:(NSArray<NSOperation *> *)ops waitUntilFinished:(BOOL)wait NS_AVAILABLE(10_6, 4_0);
以下API就是新增執行緒依賴關係
- (void)addDependency:(NSOperation *)op;