OC 中非同步順序載入用法

weixin_33924312發表於2017-12-29

實際開發過程中,有可能會用到順序載入非同步的需求,比如先掉A介面,直到A介面呼叫完成,在呼叫B介面,以此類推C介面...

當然一兩個介面這樣寫沒問題,如果這樣的介面多了,或者其他情況就不多說了。

解決辦法:dispatch_semaphore

dispatch_semaphore是GCD用來同步的一種方式,與他相關的共有三個函式,分別是dispatch_semaphore_create,dispatch_semaphore_signal,dispatch_semaphore_wait。

例項:

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);dispatch_async(dispatch_get_global_queue(0, 0), ^{

    [self logWithBlock:^(NSString *name) {

        NSLog(@"1%@",name);

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            dispatch_semaphore_signal(semaphore);

        });       

    }];

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    [self logWithBlock:^(NSString *name) {

        NSLog(@"2%@",name);

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            dispatch_semaphore_signal(semaphore);

        });

    }];

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    [self logWithBlock:^(NSString *name) {

        NSLog(@"3%@",name);

        dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

            dispatch_semaphore_signal(semaphore);

        });

    }];

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    [self logWithBlock:^(NSString *name) {

        NSLog(@"4%@",name);

        dispatch_semaphore_signal(semaphore);

    }];

    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);

    NSLog(@"完畢");

});

輸出

1694726-82baee2d8957c3a5.png

解釋:

(1)dispatch_semaphore_create的宣告為:

  dispatch_semaphore_t  dispatch_semaphore_create(long value);

  傳入的引數為long,輸出一個dispatch_semaphore_t型別且值為value的訊號量。

  值得注意的是,這裡的傳入的引數value必須大於或等於0,否則dispatch_semaphore_create會返回NULL。

  (關於訊號量,我就不在這裡累述了,網上很多介紹這個的。我們這裡主要講一下dispatch_semaphore這三個函式的用法)。


(2)dispatch_semaphore_signal的宣告為:

  long dispatch_semaphore_signal(dispatch_semaphore_t dsema)

  這個函式會使傳入的訊號量dsema的值加1;(至於返回值,待會兒再講)


 (3) dispatch_semaphore_wait的宣告為:

  long dispatch_semaphore_wait(dispatch_semaphore_t dsema, dispatch_time_t timeout);

  這個函式會使傳入的訊號量dsema的值減1;

  這個函式的作用是這樣的,如果dsema訊號量的值大於0,該函式所處執行緒就繼續執行下面的語句,並且將訊號量的值減1;

  如果desema的值為0,那麼這個函式就阻塞當前執行緒等待timeout(注意timeout的型別為dispatch_time_t,

  不能直接傳入整形或float型數),如果等待的期間desema的值被dispatch_semaphore_signal函式加1了,

  且該函式(即dispatch_semaphore_wait)所處執行緒獲得了訊號量,那麼就繼續向下執行並將訊號量減1。

  如果等待期間沒有獲取到訊號量或者訊號量的值一直為0,那麼等到timeout時,其所處執行緒自動執行其後語句。

相關文章