Swift 3 - Как создать последовательную очередь, которая ожидает завершения закрытия, чтобы продолжать выполнять рабочие элементы

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

Идея в том, что одна из функций возвращает блок. Этот блок должен быть каким-то образом помещен в последовательную очередь и удален из очереди при выполнении, чтобы пропустить последующие рабочие элементы. Вот пример того, чего я пытаюсь достичь:

let serialQueue = DispatchQueue(label: "print.serial.queue")

var i = 0

override func viewDidLoad() {
    super.viewDidLoad()

    printSomething() // Executes immediately
    printSomething() // Executes immediately
    let completion = printSomethingWithClosure() // Will execute when the closure is called
    printSomething() // Queued because completion hasn't been called yet
    printSomething() // Queued because completion hasn't been called yet
    completion() // The closure is executed, the queue can move on to the next work item

    // Expected output:
    // serial 1
    // serial 2
    // serial 3 (closure called)
    // serial 4
    // serial 5

}

func printSomething(){
    let workItem = DispatchWorkItem(qos: .userInitiated, flags: .assignCurrentContext) {[unowned self] in
        print("serial \(self.i)")
        self.i = self.i + 1
    }
    serialQueue.sync(execute: workItem)
}

func printSomethingWithClosure() -> (() -> ()){

    let completionHandler = {
        print("serial \(self.i) (closure called)")
        self.i = self.i + 1
    }

    // How do I queue this onto the DispatchQueue so it gets executed when the completionHandler is called?

    return completionHandler
}

Это возможно?


person Erken    schedule 09.11.2016    source источник
comment
Это можно сделать в Objective-C и Swift 2.3, используя подкласс NSOperation. В Swift 3 кажется, что мы не можем создать подкласс Operation (NSOperation). Итак, я не уверен, как мы можем сделать это в Swift 3. Вы нашли какое-либо решение для этого?   -  person KrishnaCA    schedule 02.12.2016
comment
@KrishnaCA К сожалению, пока нет, но я напишу здесь, если сделаю!   -  person Erken    schedule 03.12.2016
comment
Я могу предоставить решение для достижения этого для target-c, которое вы можете использовать в Swift 3 через соединительный заголовок.   -  person KrishnaCA    schedule 03.12.2016
comment
@KrishnaCA Хорошо, не могли бы вы опубликовать свое решение, пожалуйста? Я посмотрю, смогу ли я перевести ваш код Objective-C в Swift 3.   -  person Erken    schedule 05.12.2016
comment
проверьте мой ответ на этот вопрос. stackoverflow.com/questions/40265055/. Если у вас есть какие-либо сомнения, не стесняйтесь спрашивать   -  person KrishnaCA    schedule 05.12.2016