2016-12-05 3 views
0

У меня очень странная авария из приложения iOS. Нижеприведенная функция представляет собой реализацию некоторого протокола, поэтому я не могу изменить его декларацию, чтобы использовать обратный вызов с успехом/неудачей. Он имеет входные параметры и ожидает 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

Я подозреваю, что ваша проблема заключается в том, что, поскольку вы входите в группу отправки один раз, а затем (иногда) оставляете ее более одного раза в цикле, у вас нет сбалансированных вызовов. то есть. вы вызываете уйти больше раз, чем вы вызвали enter.

+0

Как это возможно? Код может входить в else только один раз из-за команды break, которая заканчивается while. –

+0

Я не уверен, что это причина. Теперь я вижу, что это может быть не потому, что я вижу разрыв сейчас ... однако вы можете проверить, правильно ли вы следуете стандартным шаблонам для использования группы отправки. Я вижу, что вы фактически не называете отпуск в качестве части завершения для блока очереди отправки. Я не понимаю, какое поведение вы получите с использованием шаблона, который вы используете. –

+0

Случается ли авария при каждом вводе? Или только иногда, когда вводится другое? Я бы испытал это сначала –

0

Найдено решение проблемы. Он не был связан с DispatchGroup, но с AVAssetWriter и входным массивом элементов AVTimedMetadataGroup. Каждый из этих элементов имеет временной диапазон. Если время начала для двух из них идентично, то при добавлении этих групп во время добавления эти группы будут находиться в состоянии ошибки, а поведение очень непредсказуемо. Я не знаю, почему ошибка была в этой строке во время уходящей группы, но решение для меня заключалось в том, чтобы обнаруживать группы с одинаковым временем начала и пропускать их.