ios - 在解析 JSON 数据期间在 UITableView 中滚动时卡住

标签 ios json swift multithreading uitableview

我在新闻应用程序中遇到多线程问题。问题是——当我在数据被解析和加载后滚动表格 View 时,我的应用程序经常卡住,而且它的方式太频繁了。我认为我每次都重新加载数据有点不对。

第一部分:

final let urlString = "http://api.to.parse"

这里我创建了结构数组来填充我的数据

struct jsonObjects {
        var id : Int
        var date : String
        var title : String
        var imageURL : URL

    }
    var jsonData = [jsonObjects]()

这是我的 tableView 的 viewDidLoad

override func viewDidLoad() {
    super.viewDidLoad()
    // MARK : - Download JSON info on start

    JsonManager.downloadJsonWithURL(urlString: urlString, сompletion: {(jsonArray) -> Void in

        guard let data = jsonArray else { print("Empty dude"); return;}
        for jsonObject in data {

            if let objectsDict = jsonObject as? NSDictionary {

                guard   
                    let id = objectsDict.value(forKey: "id") as? Int,
                    let date = objectsDict.value(forKey: "date") as? String,
                    let titleUnparsed = objectsDict.value(forKey: "title") as? NSDictionary,
                    let title = (titleUnparsed as NSDictionary).value(forKey: "rendered") as? String,
                    let imageString = objectsDict.value(forKey: "featured_image_url") as? String,
                    let imageURL = NSURL(string: imageString) as URL?
                else {
                    print("Error connecting to server")
                    return
                }

我将填充结构附加到数组:

                self.jsonData.append(jsonObjects(id: id, date: date, title: title,
                                                 imageURL: imageURL))

            }

        }   
        DispatchQueue.main.async(execute: { 
            self.tableView.reloadData()
        })
    })

downloadJsonWithURL 很简单:

class JsonManager {

class func downloadJsonWithURL(urlString: String, сompletion: @escaping (NSArray?) -> Void) {

    guard let url = NSURL(string: urlString) else { print("There is no connection to the internet"); return;}

    URLSession.shared.dataTask(with: url as URL, completionHandler: { (data, response, error) -> Void in

            guard let parseData = data else { print("There is no data"); return;}

                if let jsonObj = try? JSONSerialization.jsonObject(with: parseData, options: .allowFragments)
        as? NSArray {

                    сompletion(jsonObj)

                }

    }).resume()
}

最后 - 我在我的 TableViewCell 中输入:

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

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    guard let cell = tableView.dequeueReusableCell(withIdentifier: "newscell") as? NewsTableViewCell else {
        fatalError("Could not find cell by identifier")
    }

    guard let imageData = NSData(contentsOf: jsonData[indexPath.row].imageURL) else {
        fatalError("Could not find image")
    }

        cell.newsTitleLabel.text = self.jsonData[indexPath.row].title
        cell.newsTitleLabel.font = UIFont.boldSystemFont(ofSize: 20.0)
        cell.newsImageView.image = UIImage(data: imageData as Data)

    return cell
}

所以有两个问题:我应该如何分配我的线程以及我应该如何调用它们,以便我拥有流畅漂亮的 TableView 以及所有下载的数据?以及我应该如何在单元格中重新加载数据?

最佳答案

您的问题是由 imageData 阻塞主线程引起的。解决这个问题的最好方法是将所有图像下载到图像缓存中。我肯定会从 cellForRowAtIndexPath 中删除图像下载。

关于ios - 在解析 JSON 数据期间在 UITableView 中滚动时卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45701818/

相关文章:

java - JSONPath 获取 JSON 字符串形式的数组元素

swift - SpriteKit 许多来自同一图像的节点 : Load Separately or Duplicate?

ios - Swift:如何存储用户偏好?

ios - IOS 中表格 View 单元格点击的背景颜色更改

javascript - 如何在不损失任何精度的情况下在 Node.js 中存储极大的数字?

ios - 如何在 iOS 中将相机 View 方向锁定为横向?

ios - 如何将整数值解析为 Json iOS?

ios - 快速将图像覆盖到 CGRect 上

ios - 如何从表行中选择和保存多个值

ios - 从数据创建 UIImage 时崩溃