从 URL 字符串中提取的 UITableViewController 中的图像加载缓慢
Posted
技术标签:
【中文标题】从 URL 字符串中提取的 UITableViewController 中的图像加载缓慢【英文标题】:Slow loading of images in UITableViewController extracted from URL string 【发布时间】:2016-07-03 04:23:38 【问题描述】:我正在尝试将从 Web URL 提取的图像加载到每个单元格的图像视图中。
但是,当我滚动表格时,屏幕会冻结,因为我相信它正试图逐个抓取每个单元格的图像。
有没有办法让它异步?由于我在 Swift 2 上运行,当前可用的资源已过时或不兼容(运行 obj c)
我在表格视图控制器中使用的相关代码如下:
override func tableView(newsFeedTableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
let blogPost: BlogPost = blogPosts[indexPath.row]
cell.textLabel?.text = blogPost.postTitle
let unformattedDate = blogPost.postDate
//FORMATTING: Splitting of raw data into arrays based on delimiter '+" to print only useful information
let postDateArr = unformattedDate.characters.split$0 == "+".map(String.init)
cell.detailTextLabel?.text = postDateArr[0]
let url = NSURL(string: blogPost.postImageUrl)
let data = NSData(contentsOfURL: url!)
cell.imageView!.image = UIImage(data: data!)//WHY SO SLOW!?
print(blogPost.postImageUrl)
return cell
【问题讨论】:
您是否尝试过使用dataTaskWithRequest
?这使您的加载完全Asynchronous
并且不会冻结您的用户界面。您还可以使用Alamofire 出色地进行异步调用。看看吧。
【参考方案1】:
试试这个
var image: UIImage
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), () -> Void in
// Background thread stuff.
let url = NSURL(string: blogPost.postImageUrl)
let data = NSData(contentsOfURL: url!)
image = UIImage(data:data)
dispatch_async(dispatch_get_main_queue(), () -> Void in
// Main thread stuff.
cell.imageView.image = image
)
)
【讨论】:
你可以试试Alamofire
【参考方案2】:
让我们稍微清理一下您的代码。首先,您正在尝试清除 viewController 中的所有单元格。这意味着您的应用不会尝试逐个加载每张图片,而是更喜欢将所有内容放在一起。
您需要创建一个名为 PostCell 的单独文件,这将是一种 UITableViewCell。
然后您需要转到您的原型单元并将这些视图元素连接到该 PostCell,就像您将它们添加到任何其他 ViewController 一样。
现在,这里是你的 cellForRowAtIndexPath 函数的新代码:
override func tableView(newsFeedTableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
let blogPost = blogPosts[indexPath.row]
if let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as? PostCell
cell.configureCell(blogPost)
return cell
return UITableViewCell() // You need to do this because of if let
然后在那个 PostCell 上清除这个:
func configureCell(post: BlogPost)
this.textLabel.text = post.postTitle
let postDateArr = unformattedDate.characters.split$0 == "+".map(String.init)
this.detailTextLabel.text = postDateArr[0]
// I would add few if let declarations here too, but if you are sure all these forced ! variables do exciest, then its ok
let url = NSURL(string: blogPost.postImageUrl)
let data = NSData(contentsOfURL: url!)
this.imageView.image = UIImage(data: data!)
或者类似的东西。当您将这些元素连接到您的单元格时,您将获得这些元素的正确变量名称。
这应该会有所帮助。有很多教程如何制作自定义 tableviewcell。他们中的一些人建议将所有声明放在该 cellForRowAtIndexPath 中,但我发现它很快就会出现问题。
所以...我的建议很简单...创建一个自定义的 tableviewcell。
希望这会有所帮助! :)
【讨论】:
【参考方案3】:要在每个单元格上加载图像,请使用 SDWebImage 第三方库。您可以使用 pod 将其添加为 put pod 'SDWebImage' 它提供了各种方法来加载图像,有缓存或没有异步缓存。使用缓存,您不必担心每次单元格出现在屏幕上时加载图像数据。试试这个
override func tableView(newsFeedTableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell
if let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as? PostCell
--reset your cell here--
// cell.imageView.image = nil
cell.imageView.sd_setImageWithURL(YOUR_URL, placeholderImage: UIImage(named: ""))
(UIImage img, NSError err, SDImageCacheType cacheType, NSURL imgUrl) -> Void in
// Do awesome things
-- configure your cell here --
【讨论】:
以上是关于从 URL 字符串中提取的 UITableViewController 中的图像加载缓慢的主要内容,如果未能解决你的问题,请参考以下文章