一扯再、業(yè)務(wù)場(chǎng)景。
各個(gè)方法都是異步址遇,但需要他們順序執(zhí)行。如提交信息C(submitC)之前需要獲取B(getB),而獲取B(getB)斋竞,則需要先獲取A(getA)倔约。getA-->getB--submitC。
二坝初、常規(guī)操作浸剩。
使用回調(diào)钾军,既在getA的成功回調(diào)里面執(zhí)行g(shù)etB,在getA的成功回調(diào)里面執(zhí)行submitC绢要。此方法吏恭,如果可能會(huì)嵌套過(guò)多,不易于維護(hù)和閱讀重罪。
三樱哼、使用GCD信號(hào)量()反其道而行之,先上代碼再說(shuō)原理剿配。
- (void)getA {
? NSLog(@"開(kāi)始A");
? ? dispatch_semaphore_t sema = dispatch_semaphore_create(0);
?[[HttpRequest sharedInstance] getA:^(NSDictionary *result) {
? ? ? ? NSLog(@"A結(jié)束");
? ? ? ? dispatch_semaphore_signal(sema);
? ? } failure:^(NSError *error) {
? ? ? ? NSLog(@"A結(jié)束");
? ? ? ? dispatch_semaphore_signal(sema);
? ? }];
?NSLog(@"A等待");
? ? dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
? ? NSLog(@"A完成");
}
- (void)getB {
? ? NSLog(@"開(kāi)始B");
? ? dispatch_semaphore_t sema = dispatch_semaphore_create(0);
? ? [[HttpRequest sharedInstance] getB:^(NSDictionary *result) {
? ? ? ? NSLog(@"B結(jié)束");
? ? ? ? dispatch_semaphore_signal(sema);
? ? } failure:^(NSError *error) {
? ? ? ? NSLog(@"B結(jié)束");
? ? ? ? dispatch_semaphore_signal(sema);
? ? }];
? ? NSLog(@"B等待");
? ? dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
? ? NSLog(@"B完成");
}
- (void)submitC {
? ? NSLog(@"開(kāi)始C");
? ? dispatch_semaphore_t sema = dispatch_semaphore_create(0);
? ? [[HttpRequest sharedInstance] submitC:^(NSDictionary *result) {
? ? ? ? NSLog(@"C結(jié)束");
? ? ? ? dispatch_semaphore_signal(sema);
? ? } failure:^(NSError *error) {
? ? ? ? NSLog(@"C結(jié)束");
? ? ? ? dispatch_semaphore_signal(sema);
? ? }];
? ? NSLog(@"C等待");
? ? dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
? ? NSLog(@"C完成");
}
- (void)submitAll{
? ? NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
? ? ? ? [self getA];
? ? }];
? ? NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
? ? ? ? [self getB];
? ? }];
? ? NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
? ? ? ? [self submitC];
? ? }];
? ? [operation2 addDependency:operation1];
? ? [operation3 addDependency:operation2];
? ? NSOperationQueue *queue = [[NSOperationQueue alloc] init];
? ? [queue addOperations:@[operation1,operation2,operation3] waitUntilFinished:NO];
}
```
四.關(guān)于信號(hào)量搅幅。
1、信號(hào)量(Semaphore)簡(jiǎn)介
Dispatch Semaphore是持有計(jì)數(shù)的信號(hào)呼胚,該信號(hào)是多線程編程中的計(jì)數(shù)類(lèi)型信號(hào)茄唐。當(dāng)改計(jì)數(shù)為0時(shí)會(huì)等待(直到超時(shí)),當(dāng)改計(jì)數(shù)為0時(shí)等待結(jié)束蝇更,可以通過(guò)沪编。
2、GCD信號(hào)量(dispatch_semphore_t)
A年扩、創(chuàng)建信號(hào)量
方法:
```
dispatch_semaphore_create(long value);
```
說(shuō)明:value信號(hào)量的初數(shù)量(>=0)蚁廓。
注意:傳遞一個(gè)小于零的值將會(huì)返回NULL。
如果 value > 0常遂,就相當(dāng)于創(chuàng)建了個(gè)信號(hào)量纳令,并同時(shí)發(fā)出value個(gè)信號(hào)。
如果 value = 0克胳,就相當(dāng)于單純僅僅創(chuàng)建了個(gè)信號(hào)量平绩,還沒(méi)發(fā)信號(hào)。
如果 value < 0漠另,直接failure捏雌,返回一個(gè)NULL。
B笆搓、發(fā)送信號(hào)量
方法:
```
dispatch_semaphore_signal(dispatch_semaphore_t dsema);
```
說(shuō)明:傳入所要發(fā)送信號(hào)的信號(hào)量性湿。信號(hào)計(jì)數(shù)+1。
3. 等待信號(hào)量
方法:
```
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);
說(shuō)明:傳入所要等待信號(hào)的信號(hào)量满败。信號(hào)計(jì)數(shù)-1肤频。
4實(shí)例說(shuō)明。上面實(shí)例中dispatch_semaphore_create時(shí)信號(hào)計(jì)數(shù)為0算墨,dispatch_semaphore_signal信號(hào)計(jì)數(shù)+1宵荒。
如果有通過(guò)dispatch_semaphore_wait函數(shù)等待Dispatch Semaphore的計(jì)數(shù)值增加的線程,會(huì)由系統(tǒng)喚醒最先等待的線程執(zhí)行。