我已经向服务器实现了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)命令打印空数组。在调试窗口中,我看到其中没有任何内容。
BUT。如果我点击那个应该打印这个变量的按钮 - 它会成功打印一个包含40个元素的数组。 任何人都可以解释为什么它这样工作?
我原本期望这个变量应该用viewdidload方法中的数据填充。
答案 0 :(得分: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()