我有这段代码:
override func viewDidLoad() {
super.viewDidLoad()
navigationItem.title = "Tavolo n° " + UserDefaults.standard.string(forKey: "number")!
self.navigationController?.isNavigationBarHidden = false
navigationController?.navigationBar.barTintColor = UIColor(red: 0.30, green: 0.69, blue: 0.31 , alpha: 1.0)
navigationController?.navigationBar.titleTextAttributes = [NSAttributedStringKey.foregroundColor:UIColor.white]
navigationController?.navigationBar.tintColor = UIColor.white;
pickerView.delegate = self
pickerView.dataSource = self
name.delegate = self
let myUrl = NSURL(string: "http://192.168.1.116/myorder/data/fetch_name.php");
let request = NSMutableURLRequest(url: myUrl! as URL);
request.httpMethod = "POST";
let postString = "number=\(UserDefaults.standard.integer(forKey: "number"))";
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
}
var _: NSError?
do{
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as? NSArray
if let parseJSON: NSArray = json {
for index in 0...parseJSON.count-1 {
if (parseJSON[index] is NSNull){
let myAlert = UIAlertController(title: "Attenzione\n", message: "Nessun nominativo per questo tavolo", preferredStyle: UIAlertControllerStyle.alert);
let okAction = UIAlertAction(title: "Ok", style: UIAlertActionStyle.default){ action in }
myAlert.addAction(okAction);
self.present(myAlert, animated: true, completion: nil);
}else{
let nomi = parseJSON[index] as! [String:Any]
ViewController.listNames.append(nomi["name"] as! String)
}
}
}
}catch{
print("error=\(error)")
return
}
}
task.resume();
print(ViewController.listNames)
selectedName = ViewController.listNames[0]
NotificationCenter.default.addObserver(self, selector: #selector(NamesVC.keyboardWillShow(sender:)), name: NSNotification.Name.UIKeyboardWillShow, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(NamesVC.keyboardWillHide(sender:)), name: NSNotification.Name.UIKeyboardWillHide, object: nil)
}
有时候,在打印ViewController.listNames的第一个元素之前,响应会返回,但有时候并不会打印任何内容。 我怎么能等到响应返回?我在stackOverflow上尝试过其他答案,但我不能这样做
答案 0 :(得分:1)
发生这种情况是因为当您resume
任务时,它会通过互联网上传并获取数据,这可能需要一些时间。因此,resume
立即完成,而不是等到网络连接完成。您的print
位于下一行。有时网络连接会很快,并且会在到达print
之前完成。其他时候它不会那么快,print
首先发生。这是一个竞争条件的典型例子 - 两件事彼此分开,并且不可预测哪一件将首先完成。
所有这一切都是为什么任务有一个完成块 - 这是以if error != nil{
开头的闭包。在任务完成之前,该闭包内的代码不会发生。
您应该将print
语句放在该闭包中,以便在发生之前确保网络连接已完成。