代码之家  ›  专栏  ›  技术社区  ›  Prabhu

调度组似乎太早接到通知

  •  0
  • Prabhu  · 技术社区  · 7 年前

    我正在尝试使用这里建议的调度组 https://stackoverflow.com/a/35906703/406322

    但是,似乎在for循环的所有迭代完成之前调用了myGroup.notify。我做错什么了?

    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 回复  |  直到 7 年前
        1
  •  2
  •   James Woodrow    7 年前

    不确定,但你的 print("Finished request \(user.id)") 从线程调用,因此可以在 print("Finished all requests.")

    尝试替换

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

    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
    

    一秒钟后

    Finished request 1
    Finished request 2
    Finished all requests.