Как вы ждете обработчик завершения основной очереди?

Что я пытаюсь сделать, так это последовательно выполнить цикл for, в котором я жду завершенияHandler() перед началом следующей итерации.

  • Я должен дождаться возврата обработчика завершения перед итерацией
  • Гарантированный возврат к обработчику завершения
  • Я пытаюсь синхронно ждать в очереди с более низким приоритетом

Код:

// we're on the main queue
for index in 0..<count {
    var outcome: Any?
    let semaphore = DispatchSemaphore(value: 0)
    let queue = DispatchQueue(label: "\(index) iteration")
    // this will access a UI component and wait for user to
    // enter a value that's passed to the completion handler
    funcWithCompletionHandler() { [weak self] (result) in
        outcome = result
        semaphore.signal()
    }
    // wait here for the completion handler to signal us
    queue.sync {
        semaphore.wait()
        if let o = outcome {
            handleOutcome(outcome)
        }
    }
    // now, we iterate
}

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


person Marvin K. Bellamy    schedule 26.11.2017    source источник
comment
Никогда не ждите, пока не появится основной поток. И не лучше синхронно отправить это ожидание в другую очередь. Удалите семафоры и вызовите обработчик завершения в блоке завершения исходного асинхронного вызова. Или, если есть какая-то причина, по которой вы считаете, что не можете этого сделать, объясните почему, и мы можем предложить альтернативы.   -  person Rob    schedule 27.11.2017
comment
Я не уверен, что вы подразумеваете под вызовом обработчика завершения... Подробнее, закрытие funcWithCompletionHandler() ускользает. Он открывает модальный дочерний контроллер представления, который вызывает обработчик завершения при увольнении с введенным пользователем значением результата.   -  person Marvin K. Bellamy    schedule 27.11.2017


Ответы (1)


Я предпочитаю работать с фоновой группой, вы можете создать ее экземпляр в своем классе следующим образом: var group = DispatchGroup()

    DispatchQueue.global(qos: .background).async {
        self.group.wait()

       // this part will execute after the last one left
       // .. now, we iterate part
    }


    for index in 0..<count {
        var outcome: Any?
        let queue = DispatchQueue(label: "\(index) iteration")



        funcWithCompletionHandler() { [weak self] (result) in
            if let strongSelf = self {
                outcome = result
                strongSelf.group.enter() // group count = 1
            }

        }

        queue.sync {
            if let o = outcome {
                handleOutcome(outcome)
                self.group.leave()
                // right here group count will be 0 and the line after wait will execute
            }
        }
    }
person Gustavo Vollbrecht    schedule 26.11.2017
comment
Спасибо, это то, что я пытался сделать, но из-за другой проблемы с пользовательским интерфейсом было непонятно, работает ли это. - person Marvin K. Bellamy; 28.11.2017