从URL字符串中提取的UITableViewController中的图像加载缓慢

时间:2016-07-03 04:23:39

标签: ios swift uitableview uiimageview

我正在尝试将从网址中提取的图片加载到每个单元格的图片视图中。

但是,当我滚动表格时,屏幕会冻结,因为我相信它试图逐个抓取每个单元格的图像。

有没有办法可以让它异步?当我在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
}

3 个答案:

答案 0 :(得分: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
            })
        })

答案 1 :(得分:0)

让我们清理你的代码。首先,您试图在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。

希望这有帮助! :)

答案 2 :(得分:0)

要在每个单元格上加载图像,请使用SDWebImage第三方库。您可以使用pod添加它,因为它放在 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 --
}