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)
}
}
}
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
}
答案 0 :(得分:0)
您可以使用PFImageView
免费获得此功能,您可以编写更少的代码来实现所需的效果。设置loadInBackground:
属性后,只需致电file
即可。
https://parse.com/docs/ios/api/Classes/PFImageView.html
至于UI滞后,在仪器中的配置文件确定什么是如此昂贵,以至于它导致明显的滞后。
答案 1 :(得分:0)
有几点想法:
您应该确认此完成块是否在主线程上运行(检查NSThread.isMainThread
),如果没有,请确保将图像视图的更新分发回主线程,例如dispatch_async(dispatch_get_main_queue()) { ... }
。尝试从后台线程执行UIKit控件的更新可能会导致行为不一致,因此请确保仅从主线程更新UI。
您应该考虑用户在表格视图中快速向下滚动和备份的含义。您的代码将导致重新获取先前检索的图像。
有时,基础NSURLCache
会优雅地处理此问题,为您缓存图像。在其他情况下,它不会。 (遗憾的是,网络请求的缓存由一些相当不透明的标准决定,并且根据服务器实现,您可能无法对此进行大量控制。)
您可能需要确认自己的行为,并在之前下载的图片中实施自己的缓存(例如NSCache
)并在再次检索图像之前进行检查。
我确保将此过程与网络链接调节器一起测试,以便您可以在不太理想的环境(即实际情况)中确认应用程序的行为。
与您的问题无关,异步更新单元格有两个问题:
如果在图像检索完成之前单元格滚出视图,则单元格可能已被重用,并且单元格可能已被重用于表格中的另一行。 (通过运行带有网络链路调节器的应用程序来测试这一点,将网络响应时间降低到更糟糕的蜂窝连接器。)这个问题可以表现为一个闪烁的"图像或用与其他细胞相关的图像替换图像。
您通常通过调用tableView.cellForRowAtIndexPath(indexPath)
(UITableView
方法解决此问题,不要与类似命名的UITableViewDataSource
方法混淆),如果此索引将返回nil
路径已滚动离开屏幕,如果单元格可见,则会返回UITableViewCell
。在进行单元格的最终异步填充时,请使用此值而不是先前建立的cell
值。
如果在异步检索图像的过程中有可能重新加载表(即数据源已更改),您实际上可能希望返回模型,识别相应的索引路径与您刚刚异步下载的图像相关联。
底线,想象一下堕落的情况,花了一分钟左右来检索图像(不太可能,只是想象)。仔细考虑与之相关的突发事件(滚动关闭并随后重复使用的单元格,图像的indexPath可能不再有效,等等)。确保你优雅地处理这些突发事件。