一个接一个地执行一段代码

时间:2018-02-21 11:43:45

标签: ios swift grand-central-dispatch

作为我正在创建的应用程序的一部分,我实现了一个运行跟踪功能。我有大部分代码,但我有一段代码几乎执行得太快,我需要在下一段代码执行之前从newRun.php脚本回复,这是由于它返回一个ID我要求执行下一段代码。

    @IBAction func stopRun(_ sender: Any)
    {
       startButton.isHidden=false
       stopButton.isHidden=true
       saveRun()
    }

上面是运行saveRun的代码部分。在此按钮上单击我希望它在'run_history'表中创建新记录。只有这个已经完成,然后我想让它用newRun.php脚本返回的run_id创建新记录,其中包括运行的所有经度和纬度。

    private func saveRun()
    {

首先执行。

    let request = NSMutableURLRequest(url: NSURL(string: "../newRun.php")! as URL)
    request.httpMethod = "POST"
    let postString = "id=\(MainMenuViewController.myVariables.user_id)"
    request.httpBody = postString.data(using: String.Encoding.utf8)



    let task = URLSession.shared.dataTask(with: request as URLRequest)
    {
        data, response, error in



        if error != nil
        {
            print("error=\(String(describing: error))")
            return
        }

        print("response = \(String(describing: response))")

        let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
        MainMenuViewController.myVariables.new_run_id = responseString! as String
        print ("Run ID =\(MainMenuViewController.myVariables.new_run_id))")
    }
    task.resume()

第二次被执行。

    for location in self.locationList
    {
        var timestamp = location.timestamp
        var latitude:String = String(format:"%f", location.coordinate.latitude)
        var longitude:String = String(format:"%f", location.coordinate.longitude)

        print("Timestamp is \(timestamp)")
        print("latitude is \(latitude)")
        print("longitude is \(longitude)")
        let requestGps = NSMutableURLRequest(url: NSURL(string: "../newRunGps.php")! as URL)
        requestGps.httpMethod = "POST"
        let postStringGps = "id=\(MainMenuViewController.myVariables.new_run_id)&lng=\(longitude)&lat=\(latitude)&time=\(timestamp)"
        requestGps.httpBody = postStringGps.data(using: String.Encoding.utf8)

        let taskGps = URLSession.shared.dataTask(with: requestGps as URLRequest)
        {
            dataGps, responseGps, errorGps in

            if errorGps != nil
            {
                print("error=\(String(describing: errorGps))")
                return
            }

            print("response = \(String(describing: responseGps))")

            let responseStringGps = NSString(data: dataGps!, encoding: String.Encoding.utf8.rawValue)
            print ("responseString =\(responseStringGps!))")
        }
        taskGps.resume()
    }

}

我见过DispatchQueue和DispatchGroup的提及,但我不确定如果有人可以帮我解决这个问题,我会如何在我的代码中使用这些?

3 个答案:

答案 0 :(得分:0)

您可以尝试这样的事情:

DispatchQueue.main.asyncAfter(deadline: .now() + .seconds(4), execute: {
                    for vc in (self.navigationController?.viewControllers ?? []) {
                        if vc is DashboardViewController {
                            self.navigationController?.popToViewController(vc, animated: true)
                            break
                        }
                    }
                })

答案 1 :(得分:0)

你也可以使用"推迟"

{
    defer {

        //code run after below defer
    }
    defer{
        // code run first
    }

}

但请记住,这个推迟会在范围结束前执行

答案 2 :(得分:0)

这里的问题是MainMenuViewController.myVariables.new_run_id是在异步方法的回调中设置的,这意味着DispatchQueuedefer将在这里为您提供帮助。

处理它的最简单方法是将for循环放在回调本身内。因此,将始终确保在执行调用后仅执行

let request = NSMutableURLRequest(url: NSURL(string: "../newRun.php")! as URL)
request.httpMethod = "POST"
let postString = "id=\(MainMenuViewController.myVariables.user_id)"
request.httpBody = postString.data(using: String.Encoding.utf8)

let task = URLSession.shared.dataTask(with: request as URLRequest)
{
    data, response, error in

    if error != nil
    {
        print("error=\(String(describing: error))")
        return
    }

    print("response = \(String(describing: response))")

    let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
    MainMenuViewController.myVariables.new_run_id = responseString! as String
    print ("Run ID =\(MainMenuViewController.myVariables.new_run_id))")

    // here run the for loop
    for location in self.locationList {
         // TODO: rest of the for loop code
    }
}
task.resume()

如果您对UI做任何事情(将文本设置为UILabel等),请确保在主线程上排队代码(在您的情况下,您似乎只是将数据发送到服务器,因此您不需要需要处理那个)。