UITableView重新加载数据不起作用

时间:2014-11-22 03:53:50

标签: ios iphone uitableview swift

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

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

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

感谢

- 温尼

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()
    }    
}

3 个答案:

答案 0 :(得分:4)

好的,所以你说reloadData没有用,但这几乎肯定不是你的问题。要调试它,你应该:

  1. 确保实际调用reloadData(断点或println
  2. 在致电UITableViewDataSource(断点或打印)后,检查是否正在调用reloadData方法
  3. 检查您从网络请求中获取的results阵列(可能是println(results)
  4. 我的猜测是它在3号处失败,这意味着它与reloadData无关。也许共享的NSURLSession启用了缓存?尝试将mySession.URLCache设置为nil

答案 1 :(得分:1)

尝试替换它

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()
    })
}

答案 2 :(得分:0)

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

再次感谢各位回复。

- 温尼

PS:根据Drewag的建议,我添加了一个NSURLSessionConfiguration实例,它定义了使用NSURLSession对象下载数据时要使用的行为和策略,并将URLCache属性设置为nil以禁用缓存。

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