我有一个对象数组(其中包含从Google Places API下载照片所需的数据),当我尝试在tableView单元格中加载这些对象的元素时,图像以及titleLabels一直在切换在滚动的时候。
这是我的cellForRowAtIndexPath的tableView函数
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("TestTableViewCell", forIndexPath: indexPath) as! TestTableViewCell
let business = businessObjects[indexPath.row]
if businessShown[indexPath.row] == false{
self.getImageFromPhotoReference(business.businessPhotoReference) { (photo, error) -> Void in
cell.backgroundImage.image = photo
}
}
cell.businessNameLabel.text = business.businessName
businessShown[indexPath.row] = true
return cell
}
func getImageFromPhotoReference(photoReference: String, completion: (photo: UIImage, error: NSError?) -> Void){
let photoRequestParams = ["key":"##", "photoreference": photoReference, "maxheight": "800"]
let placePhotoURLString = self.googleClient.buildPlacePhotoURLString(photoRequestParams)
let photoRequestURL = NSURL(string: placePhotoURLString)!
self.getDataFromUrl(photoRequestURL) { (data, response, error) -> Void in
dispatch_async(dispatch_get_main_queue(), { () -> Void in
guard let data = NSData(contentsOfURL: photoRequestURL) where error == nil else { return }
let imageFile = UIImage(data: data)!
completion(photo: imageFile, error: error)
})
}
}
private func getDataFromUrl(url: NSURL, completion: ((data: NSData?, response: NSURLResponse?, error: NSError? ) -> Void)) {
NSURLSession.sharedSession().dataTaskWithURL(url) { (data, response, error) in
completion(data: data, response: response, error: error)
}.resume()
}
谢谢
答案 0 :(得分:0)
问题是异步网络调用在重用的单元格已经在其上加载新数据时完成。我的建议是使用像Kingfisher或HanekeSwift这样的图像缓存实用程序,因为它们会自动取消对单元重用的异步调用,并缓存图像,以减少网络调用。
答案 1 :(得分:0)
您的代码不是线程安全的,至少您应该在完成处理程序中检查您尝试填充图像的单元格是否仍处于启动异步图像加载时的相同位置。例如,您可以将单元格视图的标记设置为等于项目编号,如果您加载了图像但单元格标记已更改,请不要触摸此单元格的背景图像