2012-09-21 29 views
2

我有這個代碼GCD - dispatch_barrier_async - 等到完成

-(void) Method { 

    // WAIT_CODE 

    dispatch_async(myQueue,^{ CODE 1}); 
    dispatch_async(myQueue,^{ CODE 2}); 
    dispatch_barrier_async(myQueue,^{ 
     // SOME CODE 
     dispatch_async(dispatch_get_main_queue(), ^{GUI UPDATE } 
    }); 
} 

問題是,當我再次調用此方法和一些代碼還沒有執行,我需要等待WAIT_CODE繼續之前(而GUI必須保持活躍)...我該如何做到這一點?

回答

1

選項1) 添加第二個串行隊列是否有意義,這樣-method中的代碼僅在沒有其他方法調用正在執行時才運行?

例如,在主叫方將您有:

mySerialQueue = dispatch_queue_create("com.myapp.my-serial-queue", DISPATCH_QUEUE_SERIAL); 
dispatch_async(mySerialQueue, [self method]); 

選項2) 製作myQueue中的序列,而不是併發(我假設它是併發的,因爲dispatch_barrier_async()只適用於你自己的併發隊列)。

myQueue = dispatch_queue_create("com.myapp.myqueue", DISPATCH_QUEUE_SERIAL);  
dispatch_async(myQueue,^{ CODE 1}); 
dispatch_async(myQueue,^{ CODE 2}); 
dispatch_async(myQueue,^{ 
    SOME CODE 
    dispatch_async(myQueue,^{ 
     WAIT_CODE 
     dispatch_async(dispatch_get_main_queue(), ^{GUI UPDATE } 
    }); 
}); 

選項3) 重新排序的代碼SOME_CODE

dispatch_async(myQueue,^{ CODE 1}); 
dispatch_async(myQueue,^{ CODE 2}); 
dispatch_barrier_async(myQueue,^{ 
    SOME CODE // this code must block 
    WAIT_CODE // this code must block 
    dispatch_async(dispatch_get_main_queue(), ^{ GUI UPDATE } 
}); 
1

你到底做後添加WAIT_CODE?

爲什麼你必須等待?

如果當您再次調用此函數時隊列仍在執行SOME CODE,那些「新」塊將被排隊,並且直到SOME CODE塊運行之後纔會執行。我假設myQueue是一個併發隊列。屏障調用將等待所有先前入列的塊在其運行之前執行。此外,它將是唯一在隊列上運行的塊,直到它完成,然後隊列將同時恢復執行塊。

1

您也可以使用信號同步。以下是您的代碼的結構。

-(void) Method 
{ 

    // Declared dispatch_semaphore_t _synch; 
    // in init: _synch = dispatch_semaphore_create(1); 
    // in dealloc: dispatch_release(_synch); 
    // 
    // Initialized with 1 so first call goes through. 
    // Subsequent calls are serialized and must wait on a signal. 
    // 
    dispatch_time_t blockingSleepSecondsIfNotDone = 0.01; 
    while (!dispatch_semaphore_wait(wait, DISPATCH_TIME_NOW)) 
     usleep(USEC_PER_SEC * blockingSleepSecondsIfNotDone); 

    WAIT_CODE 

    dispatch_async(myQueue,^{ CODE 1}); 
    dispatch_async(myQueue,^{ CODE 2}); 
    dispatch_barrier_async(myQueue,^{ 
    SOME CODE 
    dispatch_semaphore_signal(_synch); 
    dispatch_async(dispatch_get_main_queue(), ^{GUI UPDATE } 
    }); 
}