ios - 下载数据后 TableView 未更新

标签 ios swift uitableview

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

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

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

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

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

我下载了图片,我从第一次通话中获得了它们的 URL,然后一切正常,但除非我点击该行,否则我看不到图片

请看视频,更容易理解

这是我的代码:(我给了你我的 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
    }
}

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

最佳答案

应该在主线程上调用 tableView 重新加载。在后台线程上调用 session.dataTaskWithRequest 完成 block 在后台线程上执行 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,它的缓存功能完美无缺。

关于ios - 下载数据后 TableView 未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37565918/

相关文章:

ios - UIButton 单击事件在自定义 UITableViewCell 内多次调用

ios - 使用 tableView 滑动功能从 NSUserDefaults 中删除项目时出错

ios - 如何快速裁剪照片库或相机中的 4*3 图像

iOS 应用程序不断崩溃

swift - 如何限制 UIAlertController 上的 UITextField 仅采用指定范围的数字?

IOS stackview addArrangedSubview 在特定索引处添加

ios - 带部分的 UITableView 的最佳数据源配置

ios - 无法将类型 'UITableViewCell' 的值转换为 'PFTableViewCell'

swift - PMCreateSession 不创建打印 session

ios - UitableView行选择和UIButton操作