如何在Swift中使用dispatch_async和update UI调用2个不同的api
我正在尝试进行后台api调用,并在返回结果时更新UI,我已经检查了GCD文档。如何在Swift中使用dispatch_async和update UI调用2个不同的api,swift,Swift,我正在尝试进行后台api调用,并在返回结果时更新UI,我已经检查了GCD文档。 下面的逻辑有问题吗? // get data from server let priority = DISPATCH_QUEUE_PRIORITY_BACKGROUND dispatch_async(dispatch_get_global_queue(priority, 0)) { self.getUserData() // update self.data1 global va
下面的逻辑有问题吗?
// get data from server
let priority = DISPATCH_QUEUE_PRIORITY_BACKGROUND
dispatch_async(dispatch_get_global_queue(priority, 0)) {
self.getUserData() // update self.data1 global variable
self.getCompanyData() // update self.data2 global variable
dispatch_async(dispatch_get_main_queue()) {
self.updateUI() //update UI using self.data1 and self.data2 global variable
}
}
func getUserData(){
... api1 call
... print("1")
}
func getCompanyData(){
... api2 call
... print("2")
}
func updateUI(){
... print("UI")
}
当它执行时,输出基本上是;
用户界面1
2
我想在两个api调用完成后调用updateUI函数。
下面的api调用函数之一
let fullUrl = self.apiDomain + "/user_details/" + String(self.user_id)
let url:NSURL = NSURL(string: fullUrl)!
let session = NSURLSession.sharedSession()
let request = NSMutableURLRequest(URL: url)
request.HTTPMethod = "GET"
request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData
let task = session.dataTaskWithRequest(request) {
(
let data, let response, let error) in
guard let _:NSData = data, let _:NSURLResponse = response where error == nil else {
print(error)
return
}
var apiCallResult: [String:AnyObject]?
let result = NSString(data: data!, encoding: NSUTF8StringEncoding)
do {
apiCallResult = try NSJSONSerialization.JSONObjectWithData(result!.dataUsingEncoding(NSUTF8StringEncoding)!, options: []) as? Dictionary<String, AnyObject>
} catch let error as NSError {
print(error.localizedDescription)
return
}
let aa = apiCallResult!["data"]! as! NSDictionary
print(aa)
}
task.resume()
让fullUrl=self.apiDomain+“/user\u details/”+字符串(self.user\u id)
让url:NSURL=NSURL(字符串:fullUrl)!
let session=NSURLSession.sharedSession()
let request=NSMutableURLRequest(URL:URL)
request.HTTPMethod=“GET”
request.cachePolicy=NSURLRequestCachePolicy.ReloadIgnoringCacheData
让task=session.dataTaskWithRequest(请求){
(
让数据、让响应、让错误)进入
保护let:NSData=data,let:nsurresponse=response,其中error==nil-else{
打印(错误)
返回
}
var apiCallResult:[字符串:AnyObject]?
让结果=NSString(数据:data!,编码:NSUTF8StringEncoding)
做{
apiCallResult=尝试NSJSONSerialization.JSONObjectWithData(结果!.dataUsingEncoding(NSUTF8StringEncoding)!,选项:[])作为字典
}将let错误捕获为NSError{
打印(错误。本地化描述)
返回
}
设aa=apiCallResult![“数据”]!as!NSDictionary
印刷品(aa)
}
task.resume()
您可以使用。以下是等待同步任务的代码示例:
let group = dispatch_group_create()
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { () -> Void in
print("Block1")
NSThread.sleepForTimeInterval(1.0)
print("Block1 End")
}
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { () -> Void in
print("Block2")
NSThread.sleepForTimeInterval(1.0)
print("Block2 End")
}
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) { () -> Void in
print("Block3")
}
并能产生如下产出:
Block1
Block2
Block1 End
Block2 End
Block3
如果使用调度组
等待多个异步任务
,则需要使用调度组(输入
,调度组)离开
和调度组(等待
)。下面是代码示例
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) { () -> Void in
let group = dispatch_group_create()
print("Block1")
dispatch_group_enter(group)
foo1.sendAsynchronousRequest() {
print("Block1 End")
dispatch_group_leave(group)
}
print("Block2")
dispatch_group_enter(group)
foo2.sendAsynchronousRequest() {
print("Block1 End")
dispatch_group_leave(group)
}
dispatch_group_wait(group, DISPATCH_TIME_FOREVER)
dispatch_async(dispatch_get_main_queue(), { () -> Void in
print("Block3")
})
}
有关更新问题的更多详细信息,请阅读此处。谢谢。如果
getUserData()
和getCompanyData()
都不异步工作,那么就没有问题了。就像@vadian暗示的那样,问题是因为“getUserData”和“getCompanyData”也是异步API调用。@EricD。有什么建议吗?我怎么能等他们两个都完成并更新UI呢?我想就是这样吧?self.getUserData()->self.getCompanyData()->self.updateUI()。。。。当我尝试打印时,其中3个应该在同一个调度中,正如您所提到的。但是当我调用函数而不是调用api来获取结果的print时,它会打印block3,然后再打印api调用结果。我认为getUserData()和getCompanyData()需要工作synchronous
,因为dispatch\u group\u async
已经支持asynchronous
。您能再解释一下吗?顺便说一句,谢谢你的“调度组”,它非常有用。我认为你在块1和块2的dispatch\u group\u async
中调用工作的函数asynchronous
,因此它会立即标记块1和块2已完成,并通知块3。什么是foo1和foo2?