多個網絡請求的接口設計

最近作到一個頁面裏有四個接口,每個接口返回都有對應的UI改變,因此要四個接口所有請求返回成功後,再去作UI刷新。然而因爲網絡請求用的是AFN等第三方庫,自己就是異步的,因此GCD的柵欄函數dispatch_barrier_async是沒有用的。網絡

那麼就讓他一個一個的執行,等到全部都執行完成後再去刷新UI,因而乎呢,能夠在第一個網絡請求了的返回block裏去作第二個網絡請求,以此類推就能夠完成最後的UI刷新。這個不失爲一種比較有效的方法,可是這樣寫的代碼真的挺醜的。。。。併發

若是單純的想讓這幾個網絡請求按順序執行,先進先出,那就是隊列啊,iOS裏提供的隊列管理就是GCD這個強大的c語言實現的庫。GCD裏面有一個信號量--dispatch_semaphore_t,異步

dispatch_semaphore_t

dispatch_semaphore_create(long value);建立一個信號量,若是value小於0的話,這個信號量就是nil。 dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);可讓信號量減1,若是信號量是0,那麼他會等待信號量爲非零纔會執行下一步。 dispatch_semaphore_signal(dispatch_semaphore_t dsema);可讓信號量增長1.async

經過這上面的方法,咱們能夠一開始設計信號量是0,每個網絡請求以前用dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);,請求結束回調裏用dispatch_semaphore_signal(dispatch_semaphore_t dsema);這樣可讓請求按照順序執行下來。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);
    });
}
複製代碼

打印結果以下:spa

信號量結果.png

很清楚的看到了他們是按照順序執行的。線程

dispatch_group

最好的設計固然是他們幾個併發執行,到時候所有請求結束後再去作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(@"網絡任務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(@"網絡任務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(@"網絡任務3完成 --- %@", [NSThread currentThread]);
            dispatch_group_leave(group);
        });
        sleep(2);
        NSLog(@"任務3完成---- %@", [NSThread currentThread]);
    });



    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"最後執行 ---- %@", [NSThread currentThread]);
    });
}
複製代碼

打印的結果以下:3d

group結果.png

首先能夠發現其實這幾個任務都是在不一樣的線程的,可是最後執行的確定是最後一步!code

結束語

做爲一個程序猿,思考是最重要的,雖然如今網上不少代碼能夠用拿來主義,可是若是隻會拿來,那隻能做爲一個初級的程序猿了。因此有時候多思考,多想一想。

相關文章
相關標籤/搜索