在viewDidLoad()中的tableView数据源为空 – Swift

以下是我的ViewController代码。 GetRequest中的println打印从HTTP GET请求收到的正确数据。 在这一点上,tableData有10个键值对。 但是,如果我在viewDidLoad()中调用GetRequest()之后放置了一个断点,则tableData为空,并且tableView中不显示任何内容。 为什么是这样? 我哪里错了?

import UIKit class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { @IBOutlet var tableView: UITableView! var tableData: [String:String] = [:] let textCellIdentifier = "TextCell" func GetRequest(urlPath: String) { var LatestWaitTimes: [String:String] = [:] let url: NSURL = NSURL(string: urlPath)! let session = NSURLSession.sharedSession() let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in if error != nil { // If there is an error in the web request, print it to the console println(error.localizedDescription) } var err: NSError? var jsonResult: AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) if err != nil { // If there is an error parsing JSON, print it to the console println("JSON Error \(err!.localizedDescription)") } let json = JSON(jsonResult!) let count: Int? = json.array?.count if let ct = count { for index in 0...ct-1 { let name = json[index]["CrossingName"].string var wait = json[index]["WaitTime"].stringValue if (wait == "-1") { wait = "No Info" } else { wait += " min" } println(name!+": "+wait) LatestWaitTimes[json[index]["CrossingName"].stringValue] = wait as String? } } self.tableData = LatestWaitTimes }) task.resume() } override func viewDidLoad() { super.viewDidLoad() var apiInfo = GetWaitTimes() GetRequest(apiInfo.BorderCrossingApi+"?AccessCode="+apiInfo.AccessCode) self.tableView.delegate = self self.tableView.dataSource = self tableView.reloadData() } func numberOfSectionsInTableView(tableView: UITableView) -> Int { return 1; } func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return tableData.count } func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { var cell = tableView.dequeueReusableCellWithIdentifier(self.textCellIdentifier) as! UITableViewCell let thisEntry = self.tableData.values.array[indexPath.row] cell.textLabel?.text = thisEntry+": "+tableData[thisEntry]! return cell } func tableView(tableView: UITableView, didDeselectRowAtIndexPath indexPath: NSIndexPath) { tableView.deselectRowAtIndexPath(indexPath, animated: true) } } 

问题是GetRequestasynchronous运行。 所以你必须在dataTaskWithURLcompletionHandler里面dataTaskWithURL

 let task = session.dataTaskWithURL(url, completionHandler: {data, response, error -> Void in // do all of your existing stuff here dispatch_async(dispatch_get_main_queue()) { self.tableData = LatestWaitTimes self.tableView.reloadData() } }) task.resume() 

你可以从viewDidLoad删除reloadData

重新排列方法调用的顺序:

 override func viewDidLoad() { super.viewDidLoad() self.tableView.delegate = self self.tableView.dataSource = self var apiInfo = GetWaitTimes() GetRequest(apiInfo.BorderCrossingApi+"?AccessCode="+apiInfo.AccessCode) tableView.reloadData() } 

说明:在GetRequest()之前设置委托和数据源,所以dataSource不会为零。

试试这可能会帮助你

您可以在GetRequest函数中添加一个callback函数(用于重载tablview),并在completionHandlerparsing器json之后运行callback函数

也许当你用tableview设置委托时,tableData仍然是零(等待http响应)

这是我的代码。你可以参考

 demand.loadDataFromServer(self.view, done: { () -> Void in self.demands = demand.getDemandDataList() dispatch_async(dispatch_get_main_queue(), { () -> Void in self.tableView.reloadData() }) }) func loadDataFromServer(view:UIView,done:(() -> Void)!){ var request:HttpRequest = HttpRequest(view:view) request.GET(getDemandListURL, parameters: nil, success: { (dict) -> Void in self.demandLists = dict["data"] as NSMutableArray done() }, failed: { (dict) -> Void in }) { (error) -> Void in } }