Остановите настройку нескольких AVAudioPlayers с помощью playAtTime() в цикле for

При выборе строки следующий код устанавливает набор AVAudioPlayer для воспроизведения в определенную дату (в этом случае 50 игроков играют в интервале 1 секунду). Поскольку я хочу, чтобы весь процесс перезагрузился при касании снова, мне нужно разбить установку в цикле for, так как для настройки игроков требуется несколько секунд.

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

Я попытался использовать флаг внутри цикла for, чтобы проверить, разрешена ли настройка, но это не работает.

var players: [AVAudioPlayer] = []
var loadError: NSError?

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

  // Removes the players that have been setup already.
  players.removeAll()

  // The for loop from the previous row selection should be stopped here.
  for i in 0..<50 {
    do {
      let player = try AVAudioPlayer(contentsOfURL: soundUrls[i])
      players += [player]

      // The process of setting these up takes a few seconds, I need to break it.
      print("Firing timer")   
      player.playAtTime(player.deviceCurrentTime + NSTimeInterval(i))

    } catch let error as NSError {
      loadError = error
    }
  }
}

Случается, что настройка, инициированная предыдущим выбором строки, будет продолжаться до тех пор, пока она не будет завершена, и только тогда начнется цикл new for. Мне нужно разбить его раньше.

Я не могу понять, как это решить. Возможно, удалив процессы из основного потока (How?)? Любая помощь очень ценится!

Ответ 1

Я немного запутался в вашем заявлении о проблеме, но я все равно попробую дать предложение. Вы говорите, что вы настраиваете игроков при выборе строки, но код для их настройки находится в cellForRowAtIndexPath. Поэтому он настраивается, и воспроизведение начинается, когда ячейка возвращается и отображается в вашем представлении таблицы.

Чего именно вы пытаетесь достичь? У вас есть табличный вид с несколькими строками, и всякий раз, когда вы нажимаете на ячейку, пятьдесят звуков должны начинать играть один за другим (с интервалом в 1 секунду). Если вы снова нажмете одну и ту же ячейку, они должны остановиться и перезапустить, не так ли?

Тогда я сделаю 50 игроков в viewDidLoad вашего TableViewController. Используйте prepareToPlay(). Запускайте их при необходимости.

Затем, если вам нужно перезапустить их, просто перейдите через них, проверьте, продолжают ли они играть, используя isPlaying. При необходимости приостановите их, установите текущее время на 0 и снова вызовите playAtTime. Не удаляйте проигрыватели в AudioDidFinishPlaying. Потому что тогда вам придется воссоздать их. Просто reset их, чтобы они снова были доступны для немедленного воспроизведения.

Кстати, если вы собираетесь делать больше со звуком и хотите большего контроля и лучшей производительности, я очень рекомендую отличные фреймворки Amazing Audio Engine 2 или AudioKit