Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/113.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 为什么这段代码按这种顺序执行?寻找工艺流程的解释_Ios_Swift - Fatal编程技术网

Ios 为什么这段代码按这种顺序执行?寻找工艺流程的解释

Ios 为什么这段代码按这种顺序执行?寻找工艺流程的解释,ios,swift,Ios,Swift,在下面的代码中,我希望从属于特定社区的数据库id中提取一些属性 我进行另一个API调用以获取这些社区成员的姓名 import UIKit class ShowCommunityViewController: UIViewController { @IBOutlet weak var communityName: UILabel! var communityIsCalled: String? var comIds = [String]() var communi

在下面的代码中,我希望从属于特定
社区的数据库id中提取一些属性

我进行另一个API调用以获取这些社区成员的姓名

import UIKit

class ShowCommunityViewController: UIViewController {
    @IBOutlet weak var communityName: UILabel!
    var communityIsCalled: String?
    var comIds =  [String]()
    var communityId: Int?
    var communityPlayers =  [String]()
    var communityPlayerIds =  [String]()


    override func viewDidAppear(_ animated: Bool) {
        let myUrl = URL(string: "http://www.quasisquest.uk/KeepScore/specificCommunity.php?");
        var request = URLRequest(url:myUrl!);
        request.httpMethod = "POST";
        let postString = "id=\(comIds[communityId!])";
      //  print (postString)
        request.httpBody = postString.data(using: String.Encoding.utf8);

        let task = URLSession.shared.dataTask(with: request) { (data: Data?, response: URLResponse?, error: Error?) in

            DispatchQueue.main.async
                {
                    if error != nil {
                        print("error=\(error)")
                        return
                    }

                    do{
                        let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:AnyObject]
                     // print (json)
                       if let arr = json?["players"] as? [[String:String]] {
                            let players = arr.flatMap { $0["player_id"]!
                               // print(arr)
                          }
                        print ("one ",players)
                        self.communityPlayerIds = players
                        }

                    } catch{
                        print(error)
                    }
            }
        }
        task.resume()

        let myUrlTwo = URL(string: "http://www.quasisquest.uk/KeepScore/getPlayers.php?");
        var requestTwo = URLRequest(url:myUrlTwo!);
        requestTwo.httpMethod = "POST";
        let postStringTwo = "player_ids=\(self.communityPlayerIds)";
        print ("two ",postStringTwo)
        requestTwo.httpBody = postStringTwo.data(using: String.Encoding.utf8);

        let taskTwo = URLSession.shared.dataTask(with: requestTwo) { (data: Data?, response: URLResponse?, error: Error?) in

            DispatchQueue.main.async
                {

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

                    do{
                        let json = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [String:AnyObject]
                        // print (json)
                        if let arr = json?["player_names"] as? [[String:String]] {
                            let playerNames = arr.flatMap { $0["user_name"]!
                                // print(arr)

                            }
                            print ("three ", playerNames)
                        }



                    } catch{
                        print(error)
                    }
            }
        }
        taskTwo.resume()


    }


    override func viewDidLoad() {
        super.viewDidLoad()

        communityName.text = communityIsCalled

    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}
如果您注意到打印调试命令的顺序
one、two、three

它们实际上是按
二、一、三的顺序执行的

因为
two
one
之前执行,所以我的Post字符串没有查找姓名所需的
player\u id


有人能给我解释一下流程吗?

这是因为
数据任务(请求:)
是异步的。这两个任务几乎同时启动,但HTTP请求完成时会调用
completionHandler
。这可能会为每个请求花费不同的时间。

这是因为
dataTask(请求:)
是异步的。这两个任务几乎同时启动,但HTTP请求完成时会调用
completionHandler
。这可能会为每个请求花费不同的时间。

当您使用
DispatchQueue.main.async
将作业添加到一个可以同时运行多个作业的队列中时,这些作业中的每一个都会在不同的时间内运行,因此它们的结果不一定与代码中的顺序一致


理论上,因为我不熟悉Swift的确切部分:如果没有调用
DispatchQueue.main.async
,那么它会按顺序执行,但会阻塞,代码将等待网络请求完成后再继续,打印语句将正常运行。

当您使用
DispatchQueue.main.async
时,您将作业添加到一个可以同时运行多个作业的队列中,这些作业中的每一个都在不同的时间内运行,因此它们的结果不一定与代码中的顺序一致


从理论上讲,因为我不熟悉Swift的确切部分:如果没有调用DispatchQueue.main.async,那么它会按顺序执行它们,但会被阻塞,代码会等待网络请求完成后再继续,打印语句也会按顺序执行。

首先,让我们去掉所有内容,只在代码中留下3个
print
语句

let task = URLSession.shared.dataTask(with: request) {
    print("one")
}    
task.resume()

print("two")
let taskTwo = URLSession.shared.dataTask(with: requestTwo) {
    print("three")
}
taskTwo.resume()
URLSession
任务是异步执行的。调用
task.resume()
时,它会将指令发送到另一个线程,并立即跳到下一行,而无需等待
任务完成。与CPU的速度相比,网络请求非常慢,因此它几乎总是在
one
之前打印
two


one
three
的顺序是不确定的,这取决于服务器响应的速度更快。

首先,让我们去掉所有内容,只在代码中留下3个
print
语句

let task = URLSession.shared.dataTask(with: request) {
    print("one")
}    
task.resume()

print("two")
let taskTwo = URLSession.shared.dataTask(with: requestTwo) {
    print("three")
}
taskTwo.resume()
URLSession
任务是异步执行的。调用
task.resume()
时,它会将指令发送到另一个线程,并立即跳到下一行,而无需等待
任务完成。与CPU的速度相比,网络请求非常慢,因此它几乎总是在
one
之前打印
two


one
three
的顺序是不确定的,这取决于服务器的响应速度。

一个词:“异步”。谢谢Maddy-我是Swift的新手。你介意再详细一点吗,因为这对我来说没有任何意义。这只是一个提示,让你做一些搜索。:)想象一下,你让3个人做你的工作。首先,你问A,然后你问B,最后你问C。你会先从A,然后从B,然后从C得到结果吗?不,不确定!这取决于它们为您工作的速度:)一个词:“异步”。谢谢Maddy-我对Swift很陌生。你介意再详细一点吗,因为这对我来说没有任何意义。这只是一个提示,让你做一些搜索。:)想象一下,你让3个人做你的工作。首先,你问A,然后你问B,最后你问C。你会先从A,然后从B,然后从C得到结果吗?不,不确定!这取决于他们为你工作的速度:)太好了!非常感谢。所以作为一个解决方案。。。我是否为实现目标而错误地构建了代码?我是否应该以某种方式设置标志,使一项任务在另一项任务完成后才开始?当你说“几乎总是在一项任务之前打印两项”时,你可以去掉“几乎”。由于
viewdide
将在主线程上运行,并且“一”和“三”打印语句将被分派到主线程,因此必须先打印“二”。(除非有一个病态的应用程序调用了
viewdide
——它不应该出现在后台线程上——这超出了不应该出现的范围)太好了!非常感谢。所以作为一个解决方案。。。我是否为实现目标而错误地构建了代码?我是否应该以某种方式设置标志,使一项任务在另一项任务完成后才开始?当你说“几乎总是在一项任务之前打印两项”时,你可以去掉“几乎”。由于
viewdide
将在主线程上运行,并且“一”和“三”打印语句将被分派到主线程,因此必须先打印“二”。(除非有应用程序调用
viewdide出现的病态情况——它不应该出现——在后台线程上——超出了不应该出现的范围。)