我在新闻应用程序中遇到多线程问题。问题是——当我在数据被解析和加载后滚动表格 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/