Alamofire完成工作后如何加载视图?

  • 我的问题:

我试图加载数据从服务器,通过Alamofire之前,SubViewController加载其视图。 在编写代码之后,我没能解决Alamofire的Async Feature的问题。 在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:

testing数据是否已经由其viewDidLoad() print()中的print()加载,并通过viewWillAppear() dataRequest()加载数据。

 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中的三个variables不能被分配有效值。

三项结果全部为0。

但是如果我在dataRequest()设置了print() ,我可以得到有效的计数。

  • 我的问题:

如何确保Alamofire完成工作?

我应该把Alamofire请求function放在哪里? viewWillApper()viewDidApper()

我甚至应该在ParentViewController的PrepareForSegue()完成请求作业?

请教我如何解决这个问题。

非常感谢您的指导和时间。

伊桑·乔

您应该在viewDidLoad函数中调用Alamofire请求函数。 当你从完成块(从你打印数据的地方)得到响应时,你应该reload table data

你可以像重新加载tableview,

  self.tableView.reloadData() 

希望这会帮助:)

我注意到的第一件事是你正在做3个asynchronous请求,而不是一个。 你可以使用完成处理程序,但哪一个? 我想你有两个select。

  1. 嵌套networking电话,以便完成一个开始下一个。 这种方法的缺点是它们将按顺序运行,如果添加更多,则必须继续嵌套。 像这样的方法可能是好的,如果你只打2个电话,但除此之外,它会变得越来越困难。
  2. 使用信号灯等待所有数据从所有远程调用中加载。 使用完成处理程序来发信号灯。 如果你要使用这种方法,那么它必须在后台线程上完成,因为信号量的使用会阻塞线程,而你不希望主线程发生这种情况。

这三个电话都将同时发生。 即使AlamoFire尚未完成,这些function将会返回。

  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

如何使用信号量

我给你的问题是,如果有一些,不是所有的networking通话失败,你会怎么做?

首先用false创build一个全局的boolvariables

  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。