多個網(wǎng)絡請求的接口設計

最近做到一個頁面里有四個接口,每一個接口返回都有對應的UI改變,所以要四個接口全部請求返回成功后,再去做UI刷新。然而由于網(wǎng)絡請求用的是AFN等第三方庫,本身就是異步的,所以GCD的柵欄函數(shù)dispatch_barrier_async是沒有用的。

那么就讓他一個一個的執(zhí)行,等到所有都執(zhí)行完成后再去刷新UI,于是乎呢,可以在第一個網(wǎng)絡請求了的返回block里去做第二個網(wǎng)絡請求,以此類推就可以完成最后的UI刷新。這個不失為一種比較有效的方法,但是這樣寫的代碼真的挺丑的。。。。

如果單純的想讓這幾個網(wǎng)絡請求按順序執(zhí)行,先進先出,那就是隊列啊,iOS里提供的隊列管理就是GCD這個強大的c語言實現(xiàn)的庫。GCD里面有一個信號量--dispatch_semaphore_t,

dispatch_semaphore_t

dispatch_semaphore_create(long value);創(chuàng)建一個信號量,如果value小于0的話,這個信號量就是nil。
dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);可以讓信號量減1,如果信號量是0,那么他會等待信號量為非零才會執(zhí)行下一步。
dispatch_semaphore_signal(dispatch_semaphore_t dsema);可以讓信號量增加1.

通過這上面的方法,我們可以一開始設計信號量是0,每一個網(wǎng)絡請求之前用dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);,請求結束回調(diào)里用dispatch_semaphore_signal(dispatch_semaphore_t dsema);這樣可以讓請求按照順序執(zhí)行下來。Talk is cheep,show your the code:

- (void)semaphoretest {
    dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);

    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(2);
        NSLog(@"任務1完成---- %@", [NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
    });

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(2);
        NSLog(@"任務2完成---- %@", [NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
    });

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        sleep(2);
        NSLog(@"任務3完成---- %@", [NSThread currentThread]);
        dispatch_semaphore_signal(semaphore);
    });
}

打印結果如下:

信號量結果.png

很清楚的看到了他們是按照順序執(zhí)行的。

dispatch_group

最好的設計當然是他們幾個并發(fā)執(zhí)行,到時候全部請求結束后再去做UI的刷新。于是乎想到了CGD的group啦!GCD就是辣么強大有木有!設計如下:

- (void)groupTest {
    dispatch_queue_t quete = dispatch_queue_create("XIAXIAQUEUE", DISPATCH_QUEUE_CONCURRENT);
    dispatch_group_t group = dispatch_group_create();

    dispatch_group_enter(group);
    dispatch_group_async(group, quete, ^{
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            sleep(5);
        
            NSLog(@"網(wǎng)絡任務1完----%@", [NSThread currentThread]);
            dispatch_group_leave(group);
        });
        sleep(2);
        NSLog(@"任務1完成---%@", [NSThread currentThread]);
    });

//    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    dispatch_group_enter(group);
    dispatch_group_async(group, quete, ^{
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            sleep(5);
        
            NSLog(@"網(wǎng)絡任務2完成----%@", [NSThread currentThread]);
            dispatch_group_leave(group);
        });
        sleep(2);
        NSLog(@"任務2完成---%@", [NSThread currentThread]);
    
    });

//    dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    dispatch_group_enter(group);
    dispatch_group_async(group, quete, ^{
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            sleep(5);
        
            NSLog(@"網(wǎng)絡任務3完成 --- %@", [NSThread currentThread]);
            dispatch_group_leave(group);
        });
        sleep(2);
        NSLog(@"任務3完成---- %@", [NSThread currentThread]);
    });



    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"最后執(zhí)行 ---- %@", [NSThread currentThread]);
    });
}

打印的結果如下:

group結果.png

首先可以發(fā)現(xiàn)其實這幾個任務都是在不同的線程的,但是最后執(zhí)行的肯定是最后一步!

結束語

作為一個程序猿,思考是最重要的,雖然現(xiàn)在網(wǎng)上很多代碼可以用拿來主義,但是如果只會拿來,那只能作為一個初級的程序猿了。所以有時候多思考,多想想。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容