我试图在SubViewController加载其视图之前通过Alamofire
从服务器加载数据。编写代码后,我无法解决Alamofire的异步功能问题。在Alamofire完成其工作之前,视图始终在SubViewController中加载。
ParentViewController:
通过PrepareForSegue()
引领SubViewController的方式。
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "CellDetailSegue" {
if let indexPaths = self.dateCollectionView.indexPathsForSelectedItems() {
let subViewController = segue.destinationViewController as! SubViewConroller
}
}
SubViewController:
测试print()
中viewDidLoad()
是否已加载数据,并在dataRequest()
viewWillAppear()
加载数据
class SubViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
var availablePeriods401 = [String]()
var availablePeriods403 = [String]()
var availablePeriods405 = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.dataRequest(self.availablePeriods401)
self.dataRequest(self.availablePeriods403)
self.dataRequest(self.availablePeriods405)
print(self.availablePeriods401.count)
print(self.availablePeriods403.count)
print(self.availablePeriods405.count)
}
func dataRequest(_ target: [String]) {
Alamofire.request(.POST, "http://httpbin.org/get", parameters: ["foo": "bar"]).responseJSON {
.
.
.
target = Result
}
}
}
加载视图后,无法为SubViewController中的三个变量分配有效值。
三个输出的结果都是0。
但如果我在print()
中设置dataRequest()
,我就可以获得有效的计数。
如何确保Alamofire
完成工作?
我应该在哪里提出Alamofire请求功能? viewWillApper()
? viewDidApper()
?
我是否应该在ParentViewController的PrepareForSegue()
?
请教我如何解决这个问题。
非常感谢您的指导和时间。
Ethan Joe
答案 0 :(得分:1)
您应该在viewDidLoad
函数中调用Alamofire请求函数。当你从完成块(从那里打印数据)得到响应时,你应该reload table data
。
您可以重新加载tableview,
self.tableView.reloadData()
希望这会有所帮助:)
答案 1 :(得分:1)
我注意到的第一件事是你正在做3个异步请求,而不是一个。您可以使用完成处理程序,但哪一个?我认为你有2个选择。
这三个电话都将同时发生。即使AlamoFire尚未完成,功能也将恢复。
self.dataRequest(self.availablePeriods401)
self.dataRequest(self.availablePeriods403)
self.dataRequest(self.availablePeriods405)
无论AlamoFire是否已经完成,这些都将执行。
print(self.availablePeriods401.count)
print(self.availablePeriods403.count)
print(self.availablePeriods405.count)
使用信号量看起来像这样:
override func viewWillAppear(animated: Bool) {
// maybe show a "Please Wait" dialog?
loadMyData() {
(success) in
// hide the "Please Wait" dialog.
// populate data on screen
}
}
func loadMyData(completion: MyCompletionHandler) {
// Do this in an operation queue so that we are not
// blocking the main thread.
let queue = NSOperationQueue()
queue.addOperationWithBlock {
let semaphore = dispatch_semaphore_create(0)
Alamofire.request(.POST, "http://httpbin.org/get", parameters: ["foo": "bar1"]).responseJSON {
// This block fires after the results come back
// do something
dispatch_semaphore_signal(semaphore);
}
Alamofire.request(.POST, "http://httpbin.org/get", parameters: ["foo": "bar2"]).responseJSON {
// This block fires after the results come back
// do something
dispatch_semaphore_signal(semaphore);
}
Alamofire.request(.POST, "http://httpbin.org/get", parameters: ["foo": "bar3"]).responseJSON {
// This block fires after the results come back
// do something
dispatch_semaphore_signal(semaphore);
}
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)
completion(true)
}
}
Apple Docs - Grand Central Dispatch
我遇到的问题是,如果某些网络呼叫失败,你会怎么做?
答案 2 :(得分:-1)
首先使用false
创建一个全局bool变量 override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "CellDetailSegue" && boolVar {
if let indexPaths = self.dateCollectionView.indexPathsForSelectedItems() {
let subViewController = segue.destinationViewController as! SubViewConroller
}
}
调用具有segue名称的segue和来自almofire块的boolVar为真。