UITableView重新加载数据不起作用

问题描述:

我有一个简单的iOS应用程序编写的Swift,加载通过Internet下载的JSON数据并将其显示到UITableView中。当我第一次启动应用程序时,一切正常,表格显示正确的信息。UITableView重新加载数据不起作用

在我的应用程序,我有一个按钮,当我想重新加载数据时触发刷新。所以我在刷新刷新按钮时调用displayTable()方法,它再次下载数据,然后调用主线程上的tableView.reloadData()方法刷新数据,但重新加载似乎不起作用。我手动更改服务器上的数据并刷新,但我仍然有旧数据缓存在我的应用程序中。我可以退出/终止应用程序,并且旧数据会永久保留,除非我删除应用程序并重新安装。

我附上了我的ViewController下面的代码。我花了太多时间看这个,我似乎无法找到为什么reloadData不起作用。任何想法,提示将不胜感激。

感谢

--Vinny

class ViewController: UITableViewController { 

    var tableData = [] 

    override func viewDidLoad() { 
     super.viewDidLoad() 
    } 

    override func viewWillAppear(animated: Bool) { 
     println("viewWillAppear was just called") 
     super.viewWillAppear(true) 

     self.displayTable() 
    } 

    func displayTable() { 
     getJSONData("http://www.example.com/data.json") { (results, resultError) in 

      if (resultError == nil) { 
       if var results = results { 
        dispatch_async(dispatch_get_main_queue(), { 
         self.tableData = [] //create out data on subsequent refreshes 
         self.tableData = results 
         self.tableView.reloadData() //This doesn't appear to be working! 
        }) 
       } else { 
        self.displayErrorPopup() 
       } 
      } else { 
       self.displayErrorPopup() 
      } 
     } 
    } 

    func displayErrorPopup() { 
     let alertViewController = UIAlertController(title: "Error", message: "Couldn't connect to API", preferredStyle: .Alert) 
     let okButton = UIAlertAction(title: "OK", style: .Default, handler: nil) 
     let cancelButton = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil) 
     alertViewController.addAction(okButton) 
     alertViewController.addAction(cancelButton) 
     self.presentViewController(alertViewController, animated: true, completion: nil) 
    } 

    //todo - extract this method into it's own class 
    func getJSONData(ttAPIURL : String, completion: (resultsArray: NSArray?, resultError: NSError?) ->()){ 
     let mySession = NSURLSession.sharedSession() 
     let url: NSURL = NSURL(string: ttAPIURL)! 

     let networkTask = mySession.dataTaskWithURL(url, completionHandler : {data, response, error -> Void in 
      var err: NSError? 
      if (error == nil) { 
       var theJSON = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: &err) as NSMutableDictionary 
       let results : NSArray = theJSON["list"]!["times"] as NSArray 
       completion(resultsArray: results, resultError: error) 
      } else { 
       completion(resultsArray: nil, resultError: error) 
      } 
     }) 
     networkTask.resume() 
    } 

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return tableData.count 
    } 

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCellWithIdentifier("ttCell", forIndexPath: indexPath) as UITableViewCell 
     let timesEntry = self.tableData[indexPath.row] as NSMutableDictionary 
     cell.textLabel.text = (timesEntry["routeName"] as String) 
     return cell 
    } 

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
     return 1 
    } 

    @IBAction func refreshButtonTap(sender: AnyObject) { 
     self.displayTable() 
    }  
} 

谢谢您的回答drewag和Jirom。伟大的评论,非常有帮助。我刚刚发现了我的问题,以及之前我应该​​考虑的事情。托管我的动态JSON数据的域受CloudFlare保护,看起来我的页面规则禁用某个目录的缓存不起作用。所以所有的JSON内容都被缓存了,这就是我的应用程序不会显示新数据的原因。

再次感谢你们的回复。

--Vinny

PS:每Drewag的建议下,我加入NSURLSessionConfiguration的一个实例,它定义的行为和政策,在下载使用NSURLSession对象数据时使用,并设置Urlcache文件属性设置为无禁用缓存。

let config = NSURLSessionConfiguration.defaultSessionConfiguration() 
config.URLCache = nil 
let mySession = NSURLSession(configuration: config) 

好了,你说reloadData没有工作,但是这是几乎可以肯定不是你的问题。为了调试这个你应该:

  1. 确保reloadData实际上是被称为(断点或println
  2. 检查被称为UITableViewDataSource方法调用reloadData(断点或的println)
  3. 检查results后阵列,你从网络请求回来(可能是println(results)

我的猜测是,它是在3号的失败,这意味着它与reloadData无关。也许共享NSURLSession启用了缓存?尝试将mySession.URLCache设置为nil

+0

嗨drewag和谢谢。我已经验证reloadData是通过使用println以及调试器来调用的。我还打印出结果数组并确认正在返回正确的数据。 我需要验证UITableViewDataSources方法被调用。将回报 – 2014-11-22 14:17:38

试图取代它

override func viewWillAppear(animated: Bool) { 
    println("viewWillAppear was just called") 
    super.viewWillAppear(true) 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), {() -> Void in 
     self.displayTable() 
    }) 
}