2015-12-01 15 views
1

這裏是我的代碼,我的問題是,我想在異步調用後等待結果。所以我嘗試使用信號量,但不會調用dispatch_semaphore_signal,所以出現了死鎖。我不知道如何解決這個問題。誰能告訴我發生了什麼事,非常感謝dispatch_semaphore_signal將不會調用PHImageManager requestImageDataForAsset調用

extension PHAsset{ 

func getAVAssetRepresent() -> AVURLAsset?{ 

    var asset:AVURLAsset? 

    let semaphore = dispatch_semaphore_create(0) 

    let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 

    dispatch_async(queue) {() -> Void in 

     switch self.mediaType{ 

     case .Image: 
      PHImageManager.defaultManager().requestImageDataForAsset(self, options: nil) { (_, _, _, info) -> Void in 
       if let _ = info , let url = info!["PHImageFileURLKey"] as? NSURL{ 
        asset = AVURLAsset(URL: url) 
       } 
       dispatch_semaphore_signal(semaphore) 
      } 

     default : 
      dispatch_semaphore_signal(semaphore) 
     } 

    } 
    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); 

    return asset 
}  
+0

你信號燈的使用是correct--並根據PHImageManager類的引用,該塊應該進入,即使是在一個事件錯誤/失敗。你確定你在等待足夠的時間才決定它僵局嗎?你有沒有嘗試在你的'requestImageDataForAsset'完成塊中放置一個斷點,看看你是否曾經進入過? –

+0

我想我已經等待了足夠的時間,但它永遠不會進入'requestImageDataForAsset'完成塊,如果沒有信號量存在,完成塊將被調用 – billwang1990

回答

0

因此,在你的代碼看多一點之後,我覺得你的代碼可能會矛盾。

您創建了一個信號燈,以確保您的requestImageDataForAsset在繼續之前完成執行。這表明您希望您的請求同步執行,並且在請求完成之前您不希望發生任何事情。

但是,您也可以在全局併發調度隊列上異步調度您的requestImageDataForAsset。這樣做會建議你希望你的要求發生異步在後臺

所以我相信,如果你想你的要求發生同步,你應該簡單地刪除您dispatch_async(queue)...電話。
如果您希望異步發生,您應該刪除dispatch_semaphore

然而,如果你想保持你有現在的代碼,你將需要翻騰runloop繼續執行(特別是在這種情況下,你的要求,你異步分派的)

東西是這樣的:(原諒的Objective-C,可惜我不是在迅速自信)

while (dispatch_semaphore_wait(semaphore, DISPATCH_TIME_NOW)) 
     [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode 
           beforeDate:[NSDate dateWithTimeIntervalSinceNow:10]];