如何延迟返回调用函数swift

时间:2015-12-29 21:41:24

标签: swift location delay

在我的应用程序中,用户可以按一个按钮。这反过来会导致函数调用,如下所示:

在ViewController.Swift中

@IBAction func pickMeUpButton(sender: AnyObject) {

    sendPushNotificationController().sendPushNotification("sendRequest",userInfo: defaults.stringForKey("x73")!, userInf23: defaults.stringForKey("x23")! )

    locationController.getLocationForShortTime() // --> here i want the timer to finish the 5 seconds before proceeding

    activityIndicator.center = self.view.center

    activityIndicator.startAnimating()

    self.view.addSubview(activityIndicator)

    //activityIndicator.stopAnimating()

}

这是调用

的类函数

在getUserLocation.swift中

func initManager(){

    locationManager = CLLocationManager()
    locationManager.delegate = self
    locationManager.desiredAccuracy = kCLLocationAccuracyBest
    locationManager.requestAlwaysAuthorization()
    locationManager.startUpdatingLocation()
}

func getLocationForShortTime(){

    initManager()
    timer = NSTimer.scheduledTimerWithTimeInterval(5, target: self, selector: "stopGettingLocation", userInfo: nil, repeats: false)

}

func stopGettingLocation(){

    locationManager.stopUpdatingLocation()
}

因此,这将使应用程序获取用户位置5秒钟,然后计时器将停止更新。我想要做的是当五秒钟过去并且位置更新停止那么我希望调用函数进入下一行。

我虽然使用布尔值的一些解决方案,但它不是一个很好的解决方案。我想可能有更好的方法来做到这一点?

3 个答案:

答案 0 :(得分:2)

为了延迟函数调用,您可以使用ttheta * p1 * p3。它的语法有点难看,所以你也可以使用这个延迟函数:

dispatch_after

答案 1 :(得分:2)

其他人告诉你该怎么做,但不是为什么。

你需要调整思路。

使用像iPhone / iPad这样的事件驱动设备,您无法在主线程上停止处理5秒钟。用户界面会锁定,几秒钟后系统会将你的应用程序视为挂起。

相反,你要做的是在延迟后调用一段代码(一个闭包)。

您可以像这样重写您的功能:

@IBAction func pickMeUpButton(sender: AnyObject) 
{      
  sendPushNotificationController().sendPushNotification("sendRequest",
     userInfo: defaults.stringForKey("x73")!,
     userInf23: defaults.stringForKey("x23")! )

  initManager()

  //Start the activity indicator during the delay
  activityIndicator.center = self.view.center
  self.view.addSubview(activityIndicator)
  activityIndicator.startAnimating()

  dispatch_after(
    dispatch_time(DISPATCH_TIME_NOW, Int64(5.0 * Double(NSEC_PER_SEC))),
    dispatch_get_main_queue())
  {
    //The code in the braces gets run after the delay value
    locationManager.stopUpdatingLocation()
    activityIndicator.stopAnimating()
  }
  //dispatch_after returns immediately, so code here will run before
  //the delay period passes.
}

该按钮操作代码将:

调用initManager启动位置管理器运行。

立即创建一个活动指示器,将其添加到视图控制器的内容视图中,然后开始旋转。

然后,对dispatch_after的调用将等待5秒钟,然后在大括号中运行代码,这将停止位置管理器并停止活动指示器。

答案 2 :(得分:0)

将结束传递给getLocationForShortTime。事情结束后应该运行的那个。我无法真正测试代码,但它可能类似于:

class Handler { // <- This is the wrapper class for completion closures
    private let run: Void -> Void
    init(_ run: Void -> Void) { self.run = run }
}

lazy var locationManager: CLLocationManager! = self.lazyLocationManager()

func lazyLocationManager() -> CLLocationManager {
    let _locationManager = CLLocationManager()

    _locationManager.delegate = self
    _locationManager.desiredAccuracy = kCLLocationAccuracyBest
    _locationManager.requestAlwaysAuthorization()

    return _locationManager
}

func getLocationQuick(onComplete: Void -> Void) { // <- This takes the closure
    locationManager.startUpdatingLocation()

    let timer = NSTimer.scheduledTimerWithTimeInterval(
        5,
        target: self,
        selector: "gotLocationQuick:",
        userInfo: Handler(onComplete),  // <- Here you wrap the completion closure
        repeats: false                  //    and pass it to the timer
    )

    NSRunLoop.mainRunLoop().addTimer(timer, forMode: NSDefaultRunLoopMode)
}

func gotLocationQuick(timer: NSTimer) {
    locationManager.stopUpdatingLocation()

    let completionHandler = timer.userInfo as! Handler
    completionHandler.run()
}

@IBAction func pickMeUpButton(sender: AnyObject) {
    sendPushNotificationController().sendPushNotification(
        "sendRequest",
        userInfo: defaults.stringForKey("x73")!,
        userInf23: defaults.stringForKey("x23")!
    )

    activityIndicator.center = self.view.center
    self.view.addSubview(activityIndicator)

    activityIndicator.startAnimating()

    locationController.getLocationQuick() { // <- You post the request for
        activityIndicator.stopAnimating()   //    geolocation and indicate the code
    }                                       //    to be run once it's finished
}