UITableView慢慢加载图像

时间:2015-02-10 03:46:59

标签: uitableview swift

TableView从parse api中获取图像。但是,在滚动tableView时,图像加载时会出现延迟。

是否有一种减少滞后的有效方法?在用户滚动到单元格之前(甚至之后)加载图像的某种方法?我对处理异步调用并不太熟悉。

获取图像功能

func fetchImage(restaurantArray: PFObject!, completionHandler: ImageCompletionHandler!){
    var imageReference = restaurantArray["PhotoUploaded"] as PFFile
    imageReference.getDataInBackgroundWithBlock{
        (data, error) -> Void in

        if (error != nil){
            completionHandler(image: nil, error: error)
        }else{
            let image = UIImage(data: data)
            completionHandler(image: image, error: nil)
        }
    }
}

TableView Cell

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("RestaurantCell", forIndexPath: indexPath) as FeedCell

    cell.nameLabel.text = restaurantNames[indexPath.row]

    // check if image is empty
    if foodPhotoObjects.isEmpty {
    } else {

        self.fetchImage(self.foodPhotoObjects[indexPath.row] as? PFObject, completionHandler: {
            (image, error) -> () in
            if image != nil {
                cell.mainRestaurantImageView.image = image
                cell.mainRestaurantImageView.contentMode = .ScaleAspectFill
                cell.mainRestaurantImageView.clipsToBounds = true
            }else{
                //alert user: no image or put placeholder image
            }
        })
    }

    return cell
}

2 个答案:

答案 0 :(得分:0)

您可以使用PFImageView免费获得此功能,您可以编写更少的代码来实现所需的效果。设置loadInBackground:属性后,只需致电file即可。

https://parse.com/docs/ios/api/Classes/PFImageView.html

至于UI滞后,在仪器中的配置文件确定什么是如此昂贵,以至于它导致明显的滞后。

答案 1 :(得分:0)

有几点想法:

  1. 您应该确认此完成块是否在主线程上运行(检查NSThread.isMainThread),如果没有,请确保将图像视图的更新分发回主线程,例如dispatch_async(dispatch_get_main_queue()) { ... }。尝试从后台线程执行UIKit控件的更新可能会导致行为不一致,因此请确保仅从主线程更新UI。

  2. 您应该考虑用户在表格视图中快速向下滚动和备份的含义。您的代码将导致重新获取先前检索的图像。

    有时,基础NSURLCache会优雅地处理此问题,为您缓存图像。在其他情况下,它不会。 (遗憾的是,网络请求的缓存由一些相当不透明的标准决定,并且根据服务器实现,您可能无法对此进行大量控制。)

    您可能需要确认自己的行为,并在之前下载的图片中实施自己的缓存(例如NSCache)并在再次检索图像之前进行检查。

    我确保将此过程与网络链接调节器一起测试,以便您可以在不太理想的环境(即实际情况)中确认应用程序的行为。


  3. 与您的问题无关,异步更新单元格有两个问题:

    1. 如果在图像检索完成之前单元格滚出视图,则单元格可能已被重用,并且单元格可能已被重用于表格中的另一行。 (通过运行带有网络链路调节器的应用程序来测试这一点,将网络响应时间降低到更糟糕的蜂窝连接器。)这个问题可以表现为一个闪烁的"图像或用与其他细胞相关的图像替换图像。

      您通常通过调用tableView.cellForRowAtIndexPath(indexPath)UITableView方法解决此问题,不要与类似命名的UITableViewDataSource方法混淆),如果此索引将返回nil路径已滚动离开屏幕,如果单元格可见,则会返回UITableViewCell。在进行单元格的最终异步填充时,请使用此值而不是先前建立的cell值。

    2. 如果在异步检索图像的过程中有可能重新加载表(即数据源已更改),您实际上可能希望返回模型,识别相应的索引路径与您刚刚异步下载的图像相关联。

    3. 底线,想象一下堕落的情况,花了一分钟左右来检索图像(不太可能,只是想象)。仔细考虑与之相关的突发事件(滚动关闭并随后重复使用的单元格,图像的indexPath可能不再有效,等等)。确保你优雅地处理这些突发事件。