【问题标题】:iOS - swift 3 - DispatchGroupiOS - swift 3 - DispatchGroup
【发布时间】:2017-01-15 05:57:38
【问题描述】:

我创建了这个基本架构来处理我的网络工作,

我想让它保持模块化和结构化:

public class NetworkManager {

    public private(set) var queue: DispatchQueue = DispatchQueue(label: "com.example.app.dispatchgroups", attributes: .concurrent, target: .main)
    public private(set) var dispatchGroup: DispatchGroup = DispatchGroup()

    private static var sharedNetworkManager: NetworkManager = {
        let networkManager = NetworkManager()
        return networkManager
    }()

    private init() {}

    class func shared() -> NetworkManager {
        return sharedNetworkManager
    }

    public func getData() {
        dispatchGroup.enter()

        queue.async(group: dispatchGroup) {
            Alamofire.request(Content.url).responseJSON { response in
                switch response.result {
                case .success(let value):
                    let json = JSON(value)
                    // do some stuff and save to Content struct
                    Content.annotations += [Station(...)]

                case .failure(let error):
                    print("error: ",error)
                }
            }

            self.dispatchGroup.leave()
        }
    }

}

struct Content {

    static var url = "url"

    static var annotations = [Station]()

}

所以当我在我的单独班级中调用它时:

class MainViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // some stuff ...

        NetworkManager.shared().getData()

        NetworkManager.shared().dispatchGroup.notify(queue: DispatchQueue.main) {
            self.mapView.removeAnnotations(Content.annotations)
            self.mapView.addAnnotations(Content.annotations)
        }
    }

}

但是,似乎 DispatchGroup().notify() 是在所有请求完成之前执行的......因为没有向 mapview 添加注释。

我已经检查并加载了注释。

有人可以帮我解决这个架构吗?

谢谢和问候!

【问题讨论】:

  • 我将其更改为:networkManager.getDispatchGroup().notify(queue: DispatchQueue.main) { .. } 但它仍然是一样的......有什么建议吗?
  • @Creativecrypter 您应该将您的 dispatchGroup 声明为:public private(set) var dispatchGroup: DispatchGroup。使计算属性返回属性是没有意义的。只需直接使用该属性,并将其设置器设置为私有。
  • 嗨,我将代码更改为单例并包含您的更改,结果仍然相同:/您可以检查一下吗?
  • 与您的问题无关(现在似乎已得到解答),但您可以将共享属性简化为private static var sharedNetworkManager = NetworkManager()

标签: ios swift asynchronous architecture grand-central-dispatch


【解决方案1】:

我认为您需要将 self.dispatchGroup.leave() 放入 Alamofire 响应处理程序中。如上所述,您在排队请求后立即离开。

    queue.async(group: dispatchGroup) {
        Alamofire.request(Content.url).responseJSON { response in
            switch response.result {
            case .success(let value):
                let json = JSON(value)
                // do some stuff and save to Content struct
                Content.annotations += [Station(...)]

            case .failure(let error):
                print("error: ",error)
            }
            self.dispatchGroup.leave()
        }
    }

【讨论】:

    【解决方案2】:

    如下所示更改您的代码。

    public func getData() {
        dispatchGroup.enter()
        queue.async(group: dispatchGroup) {
            Alamofire.request(Content.url).responseJSON { response in
                switch response.result {
                case .success(let value):
                    let json = JSON(value)
                    // do some stuff and save to Content struct
                    Content.annotations += [Station(...)]
    
                case .failure(let error):
                    print("error: ",error)
                }
                self.dispatchGroup.leave() // This statement has been moved
            }
        }
    }
    

    错误是您在进入 DispatchGroup 后不久就离开了。如果您必须等待网络操作完成,您应该从响应处理程序中离开。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-11-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多