Ios Json和变量范围

Ios Json和变量范围,ios,json,swift,swift3,Ios,Json,Swift,Swift3,我的错误应该很明显,但我找不到它 我在类的开头初始化了一个全局变量: class InscriptionStageViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource { var lesSemaines = [String]() 我尝试使用这个函数用一个遥远的json文件填充这个数组 func getSemainesStages(){ let url = URL(string

我的错误应该很明显,但我找不到它

我在类的开头初始化了一个全局变量:

class InscriptionStageViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
var lesSemaines = [String]()
我尝试使用这个函数用一个遥远的json文件填充这个数组

func getSemainesStages(){
        let url = URL(string: "http://www.boisdelacambre.be/ios/json/semaines.json")
        let task = URLSession.shared.dataTask(with: url!){ (data, response, error) in
            if let content = data {
                do {
                    let myJson = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
                    let listeSemaines = myJson["semaine"] as! [[String:AnyObject]]
                    //print(listeSemaines)

                    for i in 0...listeSemaines.count-1 {
                        var tabSem = listeSemaines[i]
                        let intituleSemaine:String = tabSem["intitule"] as! String
                        //let dateSemaine:String = tabSem["date"] as! String

                        DispatchQueue.main.sync
                            {

                                self.lesSemaines.append(intituleSemaine)
                            }

                    }

                } catch
                {
                    print("erreur Json")
                }
            }

        }
        task.resume()
    }
当我在viewDidLoad中调用我的函数,然后打印我的全局数组时,它是空的(URL是正确的,json数据是正确读取的,当我读取附加在循环数组中的数据时,它打印(所以)所需的值…)


提前感谢

我已将您的代码更新为Swift 3。请将其替换为以下代码

func getSemainesStages(){
    let url = URL(string: "http://www.boisdelacambre.be/ios/json/semaines.json")
    let task = URLSession.shared.dataTask(with: url!){ (data, response, error) in
        if let content = data {
            do {
                let myJson = try JSONSerialization.jsonObject(with: content, options: JSONSerialization.ReadingOptions.mutableContainers) as! [String: Any]
                let listeSemaines = myJson["semaine"] as! [[String: Any]]

                for i in 0...listeSemaines.count-1 {
                    var tabSem = listeSemaines[i]
                    let intituleSemaine:String = tabSem["intitule"] as! String
                    self.lesSemaines.append(intituleSemaine)
                }
                print(self.lesSemaines)
            } catch {
                print("erreur Json")
            }
        }

    }
    task.resume()
}

下载需要时间。介绍另一种方法:

func updateUi() {
    print(lesSemaines)
    //pickerView.reloadAllComponents()
}
下载完成后再调用:

func getSemainesStages(){
    // ... your code 
    let task = URLSession.shared.dataTask(with: url!){ (data, response, error) in
        // ... your code        
        for tabSem in listeSemaines{
             guard let intituleSemaine = tabSem["intitule"] as? String else {
                print("erreur Json")
                continue
            }
            self.lesSemaines.append(intituleSemaine)    
        }

        // update UI *after* for loop
        DispatchQueue.main.async {
            updateUi()   
        }
        // ... your code
    }
}

你什么时候读《代码》杂志?因为我猜您的问题是由于代码的异步部分。问题是什么?数组是空的?在我的viewDidLoad中,我调用函数,然后尝试打印数组,但它是空的(当我直接在函数中打印它时,问题仍然存在);当函数print(self.lesSemaines)时,它完美地打印所有数据。但是在我的ViewDidLoad中,当我尝试打印数组时,它是空的。(我调用该函数,然后尝试打印数组)是的,因为当您在view上调用时,加载的实际上是空的,并且代码在后台线程上运行。如果要在viewDidLoad中打印,请实现完成块或将其称为sync.override func viewDidLoad(){super.viewDidLoad()getSemainesStages()print(self.lesSemaines)}您不认为它会在打印数组之前完成getSemainesStages()函数吗?是的,它会。因为下载需要时间。这就是异步调用的本质。但是,当所有操作完成后,UI会得到更新。这就是为什么我在一个额外的方法中移动了
print
。如何使调用同步?因为我想将该数组用于PickerViewer,所以您不想使其同步,因为这会在下载时阻止您的UI(冻结应用程序)。在
updateUi()
中更新pickerView。如果需要很长时间才能获得良好的用户体验,请显示
UIActivityIndicator
(加载微调器)。