同步函数调用

时间:2018-03-14 05:55:17

标签: ios swift synchronization

考虑一个场景,我有一个函数“REFRESH TOKEN”,这个函数同时用不同的方法调用,假设方法是“A”,“B”,“C”。 如果方法“A”首先调用“REFRESH TOKEN”,那么方法“B”和“C”应该等到它完成。

有人有快速代码示例吗?

我如何实现这种情况?感谢您的帮助!

let serialQueue = DispatchQueue(label: "serialQueue")
var myFlag = false


override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    self.refresh(param: 1)
    self.refresh(param: 2)
    self.refresh(param: 3)

}
func refresh(param: NSInteger) -> Void {

let absolutePath = "MY SAMPLE API"
var headers: [String: String] = Dictionary<String, String>();
headers["Content-Type"] = "application/json"


serialQueue.sync {
    print("\nEntered ", param)
Alamofire.request(absolutePath, method: .get, parameters: nil, encoding: JSONEncoding.default, headers: headers).responseString {
    response in
    switch response.result {
    case .success:
        print("SUCCESS")
        break
    case .failure(let error):
        print(error)
    }
}

}}

输出:

Entered  1
Entered  2
Entered  3
SUCCESS
SUCCESS
SUCCESS

我需要这样的输出:

Entered  1
SUCCESS
Entered  2
SUCCESS
Entered  3
SUCCESS

4 个答案:

答案 0 :(得分:2)

  • 您可以使用DispatchGroup。

    let dispatchGroup = DispatchGroup()
    
    dispatchGroup.enter()
    Method A { 
         //Refresh Token code here
          dispatchGroup.leave()
       }
    dispatchGroup.wait()
    
    dispatchGroup.enter()
    Method B { 
       //Refresh Token code here
       dispatchGroup.leave() 
    }
    dispatchGroup.wait()
    
    dispatchGroup.notify(queue: .main) {
    
    print("Both functions are invoked one after other")
    
    }
    

答案 1 :(得分:0)

请求链接是一种方式。如果你发现你必须做很多事情,那么可能会考虑期货和承诺。另一种方法是使用Dispatch Group。

请求链示例

Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"]).response { (_, _, data, error) in
            if error == nil {
                Alamofire.request(.GET, "http://httpbin.org/get2\(data.something)", parameters: ["foo": "bar"]).response { (_, _, something, error) in
                fulfill(something)
               }
            } else {
                reject(error)
            }
        }

调度组示例:

 DispatchQueue.global(qos: .userInitiated).async {
  var storedError: NSError?
  let downloadGroup = DispatchGroup() 

downloadGroup.enter() 
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": 
"bar"]).response { (_, _, data, error) in
  downloadGroup.leave() 
  }
 downloadGroup.wait()
 downloadGroup.enter()
 Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": 
 "bar"]).response { (_, _, data, error) in
  downloadGroup.leave() 
  }
  downloadGroup.wait()
downloadGroup.notify(queue: DispatchQueue.main) {
  completion?(storedError)
  }
}

如果你想看看期货和承诺Alamofire做了一个lib https://github.com/PromiseKit/Alamofire-

答案 2 :(得分:0)

简单而讨厌的方法是设置一个标志并在调用函数时检查标志并在返回时更改标志。

据我所知,更好的方法是使用operation queue

答案 3 :(得分:0)

您应该创建一个dispatchQueue(Serial)并将该代码与该队列同步。

//Create a dispatch Queue
var dispatchQueue:DispatchQueue

func refreshToken() {
    dispatchQueue.sync {
        //whatever code is there in refreshToken method
    }
}