为什么调试器显示该变量为空



我已经实现了对服务器的url请求,并使用收到的JSON。但是有一件奇怪的事情我无法解释。

我的视图控制器类:

import UIKit
class TopRatedViewController: UIViewController {
    var importedRates: NSArray = []
    var successfullyConnected: Bool = true

    @IBAction func buttonTapped(sender: AnyObject) {
        print(importedRates)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        //MARK: Connection to web service
        let urlString: String = "http://alma.com/get.php"
        let url = NSURL(string: urlString)
        let sessionConfig = NSURLSessionConfiguration.defaultSessionConfiguration()
        let session = NSURLSession(configuration: sessionConfig)
        let task = session.dataTaskWithURL(url!, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
            if error != nil {
                self.successfullyConnected = false
            }else {
                var jsonresult = NSArray()
                do {
                    jsonresult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSArray
                        self.importedRates = jsonresult
                } catch _ {
                    print("error loading rates")
                }
            }
        })
        task.resume()
        print(importedRates)
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

因此,如果我运行我的应用程序打印(导入速率)命令会打印空数组。在调试窗口中,我看到其中没有任何内容。

但是,如果我单击按钮,然后应该打印此变量 - 它成功打印了一个包含 40 个元素的数组。谁能解释为什么它会这样工作?

我期望这个变量应该在viewdidload方法中填充数据。

您正在启动viewDidLoad的异步调用,该调用在完成时设置self.importedRates = jsonresult

completionHandler中的所有内容在print(importedRates)后以非常高的概率执行,更准确地说:此时,网络请求返回(取决于您的网络和请求,几微秒到几分钟)

这就是按下按钮起作用的原因:当您按下按钮时,请求确实已完成并正确填充了数组。

强烈建议不要在主线程上使用同步请求。这可能会导致应用无响应(因为所有用户输入都在主线程上处理,只要同步调用正在等待响应,就无法继续。

相反,如果您期望的数据到达,请从completionHandler中调用视图控制器的方法,该方法以您希望使用的方式使用 now-set 属性。例如,如果您尝试填充self.tableView : UITableView!

let task = session.dataTaskWithURL(url!, completionHandler: { (data: NSData?, response: NSURLResponse?, error: NSError?) -> Void in
            if error != nil {
                self.successfullyConnected = false
            }else {
                var jsonresult = NSArray()
                do {
                    jsonresult = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as! NSArray
                        dispatch_async(dispatch_get_main_queue()) {
                        self.importedRates = jsonresult
                        self.tableView.reloadData() // look here
 }
                } catch _ {
                    print("error loading rates")
                }
            }
        })
        task.resume()

最新更新