【问题标题】:Why debugger shows that variable is empty [duplicate]为什么调试器显示变量为空[重复]
【发布时间】:2016-03-11 11:23:35
【问题描述】:

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

我的 ViewController 类:

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.
    }
}

所以如果我运行我的应用程序 print(importedRates) 命令会打印空数组。在调试窗口中,我看到里面什么都没有。

但是。如果我单击应该打印此变量的按钮 - 它成功打印了一个包含 40 个元素的数组。 任何人都可以解释为什么它会这样工作吗?

我期待这个变量应该用 viewdidload 方法中的数据填充。

【问题讨论】:

    标签: ios xcode swift nsurlrequest


    【解决方案1】:

    您正在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()
    

    【讨论】:

    • 这是有道理的。谢谢你。有没有办法创建非异步调用? :) 让所有命令一个接一个地执行
    • @Almazini,我更新了我的答案。
    • @SmokeDispanser 您是只添加了一行还是进行了更多更改?对我来说,由于某种原因它不起作用。有没有办法处理CompletionHandler?
    • 这只是一个例子。您必须使其适应您的需求。我只在self.tableView 上调用了一种方法。
    • 嗯,它与我实际需要的相似。我正在对数组进行一些转换,然后重新加载 tableview。但是当应用程序加载表是空的。
    猜你喜欢
    • 2023-03-14
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    相关资源
    最近更新 更多