2017-02-22 56 views
0

我有兩個API調用如下:dispatch_async理解執行順序

-(void) doTask1{ 

    dispatch_async(queueSerial, ^{ //B1 

    [fileObj setFileInfo:file]; 

    }); 
} 

-(void) doTask2{ 

    dispatch_async(queueSerial, ^{ //B2 

     [fileObj getFileInfo:fileName completion:^(NSError *error) { 
      dispatch_async(queueSerial2, ^{ 
       //completion work C1 
      }); 
     }] 

    }); 
} 

現在,我的問題是,從我已經明白通過閱讀GCD,如果一個進程doTask1和電話doTask2後立即調用,這將導致他們兩人在排隊,並且前進B1B2

然而,不被保證B1B2開始執行之前完全執行?因爲由B1更新的文件由B2使用。

如果B2開始執行之前B1完全結束,它可能會導致一些問題。

或者是更好地做到

-(void) doTask1{ 
    dispatch_sync(queueSerial, ^{B1}); 
} 

-(void) doTask2{ 
    dispatch_sync(queueSerial, ^{B2}); 
} 

回答

1

如果queueSerial真的是一個串行隊列,然後將B1之前完成B2開始。關於這些與稱爲doTaskN方法的關係沒有任何保證......將會受到_sync修改的影響。

如果B1或B2做任何自己調度,這也是不被序列化的控制。

+0

感謝您的評論。我編輯了我的問題來添加更多關於代碼的細節。我不明白的是,你對於「關於那些關係沒有保證」的評論是什麼意思? – ExceptionHandler

+0

我的意思是說,在異步的情況下,無論代碼調用doTask1(),doTask2()在調度工作完成之前可能已經做了各種其他操作。在同步的情況下,調用者也會暫停,直到串行隊列操作完成。 –

+0

我明白了。我理解這部分。如果B2正在將其完成處理程序分派到不同的隊列中,是否可以在B1完成之前執行完成塊?有沒有辦法確保這不會發生,並且B2中的完成塊等到B1完成? – ExceptionHandler

0

如果您使用串行隊列任務就會以相同的順序(先入先出)完成,但如果您使用併發你不會有他們完成命令的任何擔保。

-(void) doTask1{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
    //your code 
    }); 
} 

-(void) doTask2{ 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 
    //your code 
    }); 
} 

下面是GCD和的NSOperation的一個很好的解釋併發:https://www.appcoda.com/ios-concurrency/

你需要確保這兩個任務都發送到相同的隊列。

更新: 另一種方法是使用NSOperation,因爲您可以設置任務之間的依賴關係,以確保在啓動另一個之前完成一個任務。

0

如果任務,B1,它被派往串行隊列,不啓動任何異步本身,那麼你就放心,B1 B2會開始之前完成。但是,如果B1是做什麼異步(例如,一個網絡請求,等等),那麼你需要其他的模式,以確保B2沒有啓動,直到B1的異步任務完成(如實現自己完成處理,用dispatch_group_notify,包住異步定製NSOperation子類中的任務等)。

+0

我修改了這個問題多一點,並創建了一個新的問題[這裏](http://stackoverflow.com/questions/42403595/forcing-the-order-of-execution-using-dispatch-sync)。你能幫我弄清楚這個嗎?我不知道我應該如何使用'dispatch_group_notify'調用,因爲它們有兩種不同的方法 – ExceptionHandler