Уведомление группы рассылки вызвано слишком рано - PullRequest
0 голосов
/ 22 сентября 2018

Я пытаюсь использовать группу диспетчеризации, как предложено здесь https://stackoverflow.com/a/35906703/406322

Однако создается впечатление, что myGroup.notify вызывается до завершения всех итераций цикла for.Что я делаю не так?

let myGroup = DispatchGroup()

for channel in channels.subscribedChannels() {
    myGroup.enter()

    buildUser(channel) { (success, user) in
        if success {
            addUser(user)
        }

        print("Finished request \(user.id)")
        myGroup.leave()
    }
}

myGroup.notify(queue: .main) {
    print("Finished all requests.")
}

Вывод такой:

Finished request 1
Finished all requests.
Finished request 2

1 Ответ

0 голосов
/ 22 сентября 2018

Не уверен, но разве ваш print("Finished request \(user.id)") не вызывается из потока и, следовательно, может вызываться после вашего print("Finished all requests."), поскольку он находится в очереди с главным приоритетом?

попробуйте заменить

print("Finished request \(user.id)")

by:

DispatchQueue.main.async {
    print("Finished request \(user.id)")
}

Тестирование на игровой площадке работает нормально:

import Foundation
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

class User {
    var id: Int
    init(id: Int) {
        self.id = id
    }
}

class Channel {
    var user: User
    init(user: User) {
        self.user = user
    }
}

var subscribedChannels: [Channel] = []
let user1 = User(id: 1)
let user2 = User(id: 2)
subscribedChannels.append(Channel(user: user1))
subscribedChannels.append(Channel(user: user2))
let myGroup = DispatchGroup()
let bgQueue = DispatchQueue.global(qos: .background)

func doSomething(channel: Channel, callback: @escaping (Bool, User) -> Void) {
    print("called for \(channel.user.id)")
    bgQueue.asyncAfter(deadline: .now() + 1) {
        callback(true, channel.user)
    }
}

for channel in subscribedChannels {
    myGroup.enter()
    doSomething(channel: channel) { (success, user) in
        if success {
            //
        }

        print("Finished request \(user.id)")
        myGroup.leave()
    }
}

myGroup.notify(queue: .main) {
    print("Finished all requests.")
}

это печатает

called for 1
called for 2

затем через 1 секунду

Finished request 1
Finished request 2
Finished all requests.

Я не знаю ваших классов и методов, поэтому мне трудно узнать больше

...