如何等待一个函数在iOS / Swift上结束,然后再开始第二个

我基本上必须要在我的viewDidLoad中调用的方法。 第一个获取用户的search首选项,并将首选项保存到顶部的variables。 之后,我想在第二个函数中访问和使用这些variables。 但是现在variables总是零,当我想在第二个函数中访问它们时。

我如何调整我的viewDidLoad,所以第二个函数只执行一次,我的数据请求已成功执行?

var searchLocation = String() var searchLocationCoordinates = [String:Double]() var searchRange = Int() override func viewDidLoad() { super.viewDidLoad() // Gets the user's search preference getTheSearchLocationAndRange() // Loads the data from the database loadDataFromDatabase() } 

到目前为止,我已经阅读了与dispatch_asynch或完成处理程序的东西。 也许有人可以发布一些代码,我可以在我的viewDidLoad中使用,并使其工作?

你可以使用Swift闭包! 他们是为了这个。

请参阅Apple指南: closures

这是您在特定情况下需要的代码。

FinishedDownload是closures。 调用getTheSearchLocationAndRange() ,会执行其代码,直到等待该函数的所有进程completed()行为止。 一旦进程完成(例如下载), completed()调用闭包来激活在getTheSearchLocationAndRange { () -> () in定义的代码。 因此,仅当getTheSearchLocationAndRange()完全执行并且数据存在(而不是nil)时才调用loadDataFromDatabase() )。

  var searchLocation = String() var searchLocationCoordinates = [String:Double]() var searchRange = Int() typealias FinishedDownload = () -> () override func viewDidLoad() { super.viewDidLoad() getTheSearchLocationAndRange() } func getTheSearchLocationAndRange(completed: FinishedDownload) { // Code for searching Location Range HERE completed() } getTheSearchLocationAndRange { () -> () in loadDataFromDatabase() } 

我希望这解决了你的问题,并回答了你的问题:)

顺便说一下,关于“离开你的graphics用户界面”的一部分,阿拉莫菲尔自动照顾这个给你。 如果您不使用Alamofire,那么您将不得不手动将asynchronous请求分配给后台线程,以便您的GUI不会无响应。

我写了一个演示项目,并将其发布到GitHub上,以模拟处理asynchronousnetworking下载。 看看DuncanMC / SwiftCompletionHandlers 。

特别看一下asyncFetchImage()方法,它几乎确切地说明了这个线程在说什么:在内部使用一个asynchronous方法,并且在完成asynchronous加载后接收一个完成块。

这是你应该使用的一般模式。 编写一个完成块/closures的方法。 在内部,该方法调用它需要的任何asynchronous函数,然后在asynchronous方法调用的完成闭包内调用完成闭包。

函数asyncFetchImage看起来像这样:

 func asyncFetchImage(imageName imageName: String, completion: ( image: UIImage?, status: String) -> ()) { print("Entering \(#function)") //Simulate a network operation by waiting a few seconds before loading an image let nSecDispatchTime = dispatch_time(DISPATCH_TIME_NOW, Int64(3.0 * Double(NSEC_PER_SEC))) let queue = dispatch_get_main_queue() dispatch_after(nSecDispatchTime, queue) { () -> Void in let result = UIImage(named: imageName) print("Loading image in background") let status = result != nil ? "image loaded" : "Error loading image" print("About to call completion handler") completion(image: result, status: status) } print("Leaving \(#function)") } 

好的,我find了一个解决scheme。 我基本上在第一个结尾处调用函数。

所以基本上:

  var searchLocation = String() var searchLocationCoordinates = [String:Double]() var searchRange = Int() override func viewDidLoad() { super.viewDidLoad() // Gets the user's search preference getTheSearchLocationAndRange() } func getTheSearchLocationAndRange() { // Code for getTheSearchLocationAndRange() loadDataFromDatabase() } func loadDataFromDatabase(){ // Code for loadDataFromDatabase() }