【问题标题】:Swift Json Tableview laggySwift Json Tableview 滞后
【发布时间】: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 中使用 NSURLNSData。永远,永远不要使用NSData(contentsOf:) 来加载远程数据。
  • @rmaddy 谢谢!我对此很陌生,但我应该改用什么?
  • 您必须始终异步加载远程数据。通常这是通过 URLSession 完成的。但是对于带有缓存的远程表格视图图像,SDWebImage 似乎是一个流行的实用程序。

标签: ios json swift uitableview


【解决方案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"))

【讨论】:

【解决方案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,因为正如你所说,我需要缓存所有图像。我会尝试然后更新你:)
    • 很好。缓存将适用于图像等大数据。
    猜你喜欢
    • 1970-01-01
    • 2018-10-29
    • 2019-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多