Swift Json Tableview 滞后
Posted
技术标签:
【中文标题】Swift Json Tableview 滞后【英文标题】:Swift Json Tableview laggy 【发布时间】:2018-04-07 16:00:13 【问题描述】:我有问题。我在 Swift 中有这段代码,但是当我在 tableview 中滚动时它非常滞后,我不知道问题是什么......?? 它下载的图像数据每个大约 20mb(我认为)..
谢谢!
func downloadJsonWithTask()
let url = NSURL(string: urlString)
var downloadTask = URLRequest(url: (url as? URL)!, cachePolicy: URLRequest.CachePolicy.reloadIgnoringCacheData, timeoutInterval: 200)
downloadTask.httpMethod = "GET"
URLSession.shared.dataTask(with: downloadTask, completionHandler: (data, response, error) -> Void in
let jsonData = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments)
print(jsonData)
).resume()
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! TableViewCell
cell.nameLabel.text = nameArray[indexPath.row]
cell.dobLabel.text = dobArray[indexPath.row]
let imgURL = NSURL(string: imgURLArray[indexPath.row])
if imgURL != nil
let data = NSData(contentsOf: (imgURL as? URL)!)
cell.imgView.image = UIImage(data: data as! Data)
return cell
///for showing next detailed screen with the downloaded info
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
let vc = self.storyboard?.instantiateViewController(withIdentifier: "DetailViewController") as! DetailViewController
vc.imageString = imgURLArray[indexPath.row]
vc.imageString2 = imgURL2Array[indexPath.row]
vc.imageString3 = imgURL3Array[indexPath.row]
vc.imageString4 = imgURL4Array[indexPath.row]
vc.imageString5 = imgURL5Array[indexPath.row]
vc.imageString6 = imgURL6Array[indexPath.row]
vc.nameString = nameArray[indexPath.row]
vc.dobString = dobArray[indexPath.row]
vc.txtString = txtArray[indexPath.row]
vc.contactString = contactArray[indexPath.row]
self.navigationController?.pushViewController(vc, animated: true)
【问题讨论】:
可能与每个20mb有关 旁注 - 不要在 Swift 中使用NSURL
或 NSData
。永远,永远不要使用NSData(contentsOf:)
来加载远程数据。
@rmaddy 谢谢!我对此很陌生,但我应该改用什么?
您必须始终异步加载远程数据。通常这是通过 URLSession 完成的。但是对于带有缓存的远程表格视图图像,SDWebImage 似乎是一个流行的实用程序。
【参考方案1】:
因为这条线的问题
let data = NSData(contentsOf: (imgURL as? URL)!)
它阻塞了主线程,你必须在其他队列中运行它,除此之外每次滚动都会重新下载图像(无缓存),所以最好使用SDWebImage
cell.imgView.sd_setImage(with: URL(string: "http://www.example.com/path/to/image.jpg"), placeholderImage: UIImage(named: "placeholder.png"))
【讨论】:
评论不用于扩展讨论;这个对话是moved to chat。【参考方案2】:这总是会滞后的。 您在主线程中请求的图像。
尝试使用 SDWebCache 库:https://github.com/rs/SDWebImage。
1 : 会先缓存图片,避免多次 HTTP 请求。
2 : 在后台工作,因此不会影响主线程。
使用方法imageview.sd_imageFromUrl(URL(....)!)
【讨论】:
【参考方案3】:非常清楚。您从主线程询问图像数据。每当你在主线程上执行耗时的操作时,App就会卡顿。
let data = NSData(contentsOf: (imgURL as? URL)!)
目前为止对我最有效的解决方案是使用 AlamofireImage 或 Kingfisher。这需要您了解如何将库添加到您的项目中。为了方便起见,尝试使用 Cocoapods。
我假设你可以在这里使用 Cocoapods。
如果您想要缓存支持,Kingfisher 是第一位的。缓存意味着您只需要在第一次或发生更改时向服务器发出请求。它将节省您的资源等。您需要做的就是在 ViewController 中导入 Kingfisher 模块,然后它会自动扩展 UIImageView 功能并使用 Kingfisher 扩展 kf
这里是示例代码
//ViewController.swift
import Kingfisher
// Your cellForRowAt
...
if let url = URL(string: imgURLArray[indexPath.row])
cell.imgView.kf.setImage(with: url)
...
Kingfisher 将在后台执行缓存策略,以便您可以专注于应用程序。
为了放置默认图像,这对于通知用户图像非常有用,(用户希望空白白框中有一些东西 - UIImageView 而图像为零 - 在他们的屏幕中不是吗?)翠鸟帮助你和placeholder
let defaultImage = UIImage(named: "default_img")!
cell.imgView.kf.setImage(with: url, placeholder: defaultImage)
在这里Kingfisher's Github Page获取有关翠鸟的完整见解
【讨论】:
非常感谢。我之前使用过 alamofire,但后来我切换到 json 文件来存储 tableview 中的所有数据。我要测试 Kingfisher 或 AlamofireImage,因为正如你所说,我需要缓存所有图像。我会尝试然后更新你:) 很好。缓存将适用于图像等大数据。以上是关于Swift Json Tableview 滞后的主要内容,如果未能解决你的问题,请参考以下文章
swift tableview 将 reloadData 更改为 insertRows
Swift 3. 使用 Core Data 隐藏一个空的 tableView