2016-12-05 51 views
0

我從iOS App遇到非常奇怪的崩潰。下面的函數是一些協議的實現,所以我不能改變它的聲明來使用一些成功/失敗的回調函數。它具有輸入參數,並希望在輸出端使用AVAsset。我的問題是在寫資產期間,我在離開調度組(dg變量)期間出現了奇怪的崩潰。我用評論標記了崩潰的一行。這種崩潰並不總是會發生。只是不時。這是功能:Dispatch Group的奇怪行爲

func writeAsset(to url: URL, metadataArray: [AVTimedMetadataGroup]) -> AVAsset { 
     let writer = try! AVAssetWriter(url: url, fileType: AVFileTypeQuickTimeMovie) 
     writer.movieTimeScale = track.timeScale 

     // setup writer, inputs and metadata adaptor and so on ... 

     if writer.startWriting() { 
      writer.startSession(atSourceTime: kCMTimeZero) 
     } 

     let writeQueue = DispatchQueue(label: "HH.Write.Track.Queue") 

     let dg = DispatchGroup() 
     var i = 0 

     dg.enter() // Entering to the group 
     writerMetadataIn.requestMediaDataWhenReady(on: writeQueue) { 
      while writerMetadataIn.isReadyForMoreMediaData { 
       //let group = ..fetch next group to write 
       if i < metadataArray.count { 
        let group = metadataArray[i] 
        if writerMetadataAdaptor.append(group) { 
        } 
        i += 1 
       } else { 
        writerMetadataIn.markAsFinished() 
        writer.finishWriting { 
         dg.leave() // CRASH IN THIS LINE 
        } 
        break 
       } 
      } 
     } 
     dg.wait() 

     let writtenAsset = AVAsset(url: url) 
     return writtenAsset 
    } 

有人可能知道這次事故的原因是什麼?我只有來自xCode崩潰報告的這些信息。

+0

什麼是崩潰細節? –

+0

我沒有。就這一行。 –

+0

在終端中,我只有這樣的信息:(lldb) –

回答

1

我懷疑你的問題是,因爲你一次進入調度組,然後(有時)不止一次地在循環中離開它,你沒有平衡調用。即。你打電話給假的次數比你所說的要多。

+0

這是可能的嗎?代碼可以輸入到其他塊,只有一次,因爲中斷時終止指令。 –

+0

我不確定這是什麼原因。現在我看到它可能不是因爲我現在看到了休息......但是你可能想要檢查你是否正確遵循使用調度組的標準模式。我發現你實際上並沒有把離職作爲調度隊列塊完成的一部分。我不清楚你使用的模式會得到什麼樣的行爲。 –

+0

每次進入其他時間都會發生崩潰嗎?或者只有在進入其他時纔有時候?我會先測試一下 –

0

找到問題的解決方案。它與DispatchGroup無關,但與AVAssetWriter和AVTimedMetadataGroup元素的輸入數組相關。每個元素都有時間範圍。如果其中兩個的開始時間相同,則在追加這些組期間,開發者將處於錯誤狀態,行爲非常不可預測。我不知道爲什麼在離開小組的時候出現錯誤,但我的解決方案是檢測具有相同開始時間的小組並跳過它們。