UITableView与来自API的图像

UITableView是一种以列表方式显示结构化数据的好方法。 与Android不同,iOS在促进开发人员使用UITableView方面做得很好。 当您的应用程序显示来自API调用的数据时,事情的学习曲线确实陡峭。 在这里曲线不会停止变陡。 如果您计划在UITableViewCell中显示图像,它将变得有些棘手。 这正是我们今天要做的。

我们打算做什么?

我不打算深入研究UITableView实现。 我给你创造的自由,可以根据需要设计UITableViewCell并使基本应用程序正常工作。 首先使用虚拟数据和占位符图像测试UITableView始终是一个好主意。

一旦您的UITableView启动并运行了虚拟数据和占位符图像,请从GitHub API获取内容。

您可以通过请求以下URL来获得您的GitHub关注者。

https://api.github.com/users/ / followers

API响应将具有许多键值。 我们将限制本帖子的图片和名称。

假设您知道如何进行网络调用和解析响应数据以显示在UITableViewCell上,现在让我们集中讨论您应该面对的两个问题

  • 表格视图滚动很慢。
  • 滚动UITableView时,图像会更改。 用户A的个人资料图片可能与用户B的名字一起出现

问题1:为什么UITableView滞后?

当您尝试在UITableViewCell的UIImageView上呈现图像时,将进行网络调用,该网络调用将从图像url获取图像数据,然后使用响应数据创建图像。

每次创建单元时都会发生这种情况。 假设您有3个UITableViewCells,那么将有3个网络调用来获取每个单元格的图像。 当我们处理更多单元格时,随着UITableView重用单元格,此问题会放大。

我如何摆脱时滞?

为了恢复完美的滚动效果,我们可以使用多任务处理。 我们将在后台获取图像数据,并且在接收到图像数据后,将用从API调用接收到的图像替换占位符图像。
在cellForRowAtIndexPath中,

  DispatchQueue.global(qos:.background).async { 
 让url = URL(string:(activeUser?.avatarUrl)!) 
 让数据=尝试? 数据(contentsOf:url!) 
 让图像:UIImage = UIImage(data:data!)! 
  DispatchQueue.main.async { 
  self.imageCache.setObject(image,forKey:NSString(string:(activeUser?.login!)!)) 
  cell.imgFollow.image =图片 
}
  } 

但是,如果图像数据从未收到怎么办?

这是占位符为您提供帮助的地方。 如果未接收到图像数据,则UITableViewCell将具有占位符图像。

问题2:为什么图像在滚动时会不断变化?

如上所述,每次创建UITableViewCell时都会进行网络调用。 说,您的单元格已创建,图像请求已发出,但是在图像响应完成之前,您滚动到另一个单元格。 tableview不知道数据。 它只是按照提示进行操作,并将图像数据粘贴到图片中的表格单元格上的图像上。

如何防止这种情况发生?

更好的方法是利用缓存。 我们现在

  1. 创建单元格时获取图像。 每个图像只需下载一次。
  2. 使用合适的密钥(例如登录ID)缓存图像。
  3. 每次重复使用或创建单元时,请检查缓存中的图像
  4. 如果图像在缓存中,请从缓存中加载图像。
  5. 如果图像不在缓存中,请进行网络调用以获取它并将其存储在缓存中。

初始化缓存:

 让imageCache = NSCache () 

将图像保存在缓存中:

  self.imageCache.setObject(image,forKey:NSString(string:(activeUser?.login!)!)) 

加载图像:

 如果让cachedImage = imageCache.object(forKey:NSString(string:(activeUser?.login!)!))){ 
cell.imgFollow.image =缓存的图像
}其他{
//进行网络通话以获取图像
}

这是完整的GitHub项目,我在其中使用了这些代码段。