下载数据后表视图未更新

时间:2016-06-01 10:21:49

标签: ios swift uitableview

首先,为了避免我的英语不好,我上传了一个显示我的问题的视频

http://www.mediafire.com/download/j6krsa274o80ik9/Screen_Recording.mov

其次,我有一个UITableViewController,它使用远程API下载数据。数据包含许多图像URL,我的第一个问题是即使我正在执行.reloadData()函数,tableView也没有更新

我的第二个问题是在函数中:

tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

我下载了图片,我从第一次调用中得到了他们的网址,然后事件很好但我看不到图像,除非我点击了行

请看视频,更容易理解

这是我的代码:(我给了你UITableView的完整代码,因为它很简单,因为它有两个功能,而且它们让我有问题)

class Physicst: NSObject {
    let image : String
    var imageData: UIImage?
    let name : NSString
    init(image: String, name: NSString) {
        self.image = image
        self.name = name
    }
}

class PhysicistTableViewController: UITableViewController {

    var physicsts : [Physicst]?

    @IBOutlet var physicstsTableView: UITableView!



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

    func loadDataFromDBPedia()  {
        let session = NSURLSession.sharedSession()
        var url = "http://dbpedia.org/sparql/"
        let query = "http://dbpedia.org&query=select * {?o  dbo:thumbnail ?p . ?o dbo:award dbr:Nobel_Prize_in_Physics} limit 10"
        url = url + "?default-graph-uri=" + query.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!
        url = url + "&format=JSON&CXML_redir_for_subjs=121&CXML_redir_for_hrefs=&timeout=30000&debug=on"
        let request = NSMutableURLRequest(URL: NSURL(string: url)!)
        let task = session.dataTaskWithRequest(request, completionHandler: {(data, response ,error) in
            if let error = error {
                print ("\(error)")
            }
            if let response = response {
                let httpResponse = response as! NSHTTPURLResponse
                let statusCode = httpResponse.statusCode
                print("Status code = \(statusCode)")
            }
            if let data = data  {
                do {
                    let jsonResponse = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())
                    let binding = jsonResponse["results"]!!["bindings"] as! NSArray
                    for oneBinding in binding {
                        let name = oneBinding["o"]!!["value"] as! NSString
                        var image = oneBinding["p"]!!["value"] as! String
                        image = image.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
                        let physicst = Physicst(image: image, name: name)
                        if self.physicsts == nil {
                            self.physicsts = [Physicst]()
                        }
                        self.physicsts!.append(physicst)
                    }
                    self.physicstsTableView.reloadData()
                }catch _ {
                    print ("not well json-formatted response")
                }
            }
        })
        task.resume()
    }

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

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if self.physicsts == nil {
            return 0
        }else {
            return self.physicsts!.count
        }
    }


    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("physicstCell")! as UITableViewCell
        let row = indexPath.row
        let physicst = self.physicsts![row]
        cell.textLabel?.text = physicst.name as String
        if (physicst.imageData == nil) {
            let session = NSURLSession.sharedSession()
            let url = NSURL(string: physicst.image as String)
            if let url = url {
                let request = NSMutableURLRequest(URL: url)
                let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
                    if let data = data {
                        let imageData = UIImage(data: data)
                        cell.imageView?.image = imageData
                        physicst.imageData = imageData
                        self.physicstsTableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
                    }
                })
                task.resume()
            }else {
                print ("nill URL \(physicst.image)")
            }
        }else {
            cell.imageView?.image = physicst.imageData!
        }
        return cell
    }
}

**可以自由复制/粘贴它,没有自定义单元格,所以它应该可以工作**

1 个答案:

答案 0 :(得分:2)

应在主线程上调用tableView reload。 session.dataTaskWithRequest在后台线程上调用完成块,在后台线程上执行UI操作可能会导致严重后果。我相信你面临的问题只是其中一个后果。修改代码如下。

func loadDataFromDBPedia()  {
            let session = NSURLSession.sharedSession()
            var url = "http://dbpedia.org/sparql/"
            let query = "http://dbpedia.org&query=select * {?o  dbo:thumbnail ?p . ?o dbo:award dbr:Nobel_Prize_in_Physics} limit 10"
            url = url + "?default-graph-uri=" + query.stringByAddingPercentEncodingWithAllowedCharacters(.URLHostAllowedCharacterSet())!
            url = url + "&format=JSON&CXML_redir_for_subjs=121&CXML_redir_for_hrefs=&timeout=30000&debug=on"
            let request = NSMutableURLRequest(URL: NSURL(string: url)!)
            let task = session.dataTaskWithRequest(request, completionHandler: {(data, response ,error) in
                if let error = error {
                    print ("\(error)")
                }
                if let response = response {
                    let httpResponse = response as! NSHTTPURLResponse
                    let statusCode = httpResponse.statusCode
                    print("Status code = \(statusCode)")
                }
                if let data = data  {
                    do {
                        let jsonResponse = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())
                        let binding = jsonResponse["results"]!!["bindings"] as! NSArray
                        for oneBinding in binding {
                            let name = oneBinding["o"]!!["value"] as! NSString
                            var image = oneBinding["p"]!!["value"] as! String
                            image = image.stringByAddingPercentEscapesUsingEncoding(NSUTF8StringEncoding)!
                            let physicst = Physicst(image: image, name: name)
                            if self.physicsts == nil {
                                self.physicsts = [Physicst]()
                            }
                            self.physicsts!.append(physicst)
                        }
                        dispatch_async(dispatch_get_main_queue()) { () -> Void in
                             self.physicstsTableView.reloadData()
                        }
                    }catch _ {
                        print ("not well json-formatted response")
                    }
                }
            })
            task.resume()
        }


override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("physicstCell")! as UITableViewCell
        let row = indexPath.row
        let physicst = self.physicsts![row]
        cell.textLabel?.text = physicst.name as String
        if (physicst.imageData == nil) {
            let session = NSURLSession.sharedSession()
            let url = NSURL(string: physicst.image as String)
            if let url = url {
                let request = NSMutableURLRequest(URL: url)
                let task = session.dataTaskWithRequest(request, completionHandler: {(data, response, error) in
                    if let data = data {
                        dispatch_async(dispatch_get_main_queue(), { () -> Void in
                            let imageData = UIImage(data: data)
                            cell.imageView?.image = imageData
                            physicst.imageData = imageData
                            self.physicstsTableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.None)
                        })
                    }
                })
                task.resume()
            }else {
                print ("nill URL \(physicst.image)")
            }
        }else {
            cell.imageView?.image = physicst.imageData!
        }
        return cell
    }

提示

为每个单元格手动下载图像,然后将其加载到tableViewCell并处理缓存以提高滚动性能,就像在有无轮胎轮胎时重新发明轮子一样:)请考虑使用SDWebImageAFNetworking我个人使用了SDWebImage,其缓存功能完美无缺。