使用 NScache 从 UICollectionView 中的 Web 服务器加载图像时遇到一些问题。
问题:
图像未正确显示:
- 有时它们没有显示在相应的单元格中
or
- 图像在滚动时发生变化
情况:
我有 3 个数组,它们在函数 viewDidLoad() 中从 Web 服务器正确加载。这些数组是:vPrice、vTitle 和 vImages_api
-
我的单元格自定义类有:
价格标签:cell.lblPrice
标题标签:cell.lblTitle
图片:cell.imgPicture
我相信问题出在函数 func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell
它可能与我使用 NSCache 的方式有关,也可能与我使用 DispatchQueue 的方式和时间有关。
代码:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = self.collectionViewPRODUSE.dequeueReusableCell(withReuseIdentifier: "customCell", for: indexPath) as! clsCustomCell
cell.lblPrice.text = vPrice[indexPath.item]
cell.lblTitle.text = vTitle[indexPath.item]
cell.layer.borderColor = UIColor.lightGray.cgColor
cell.layer.borderWidth = 0.5
DispatchQueue.global(qos: .userInitiated).async {
//background thread
let ImageString = self.vImages_api[indexPath.item]
let imageUrl = URL(string: ImageString)
let imageData = NSData(contentsOf: imageUrl!)
// main thread to update the UI
DispatchQueue.main.async {
let key1 = self.vImages_api[indexPath.item] as AnyObject
//if i saved allready my image in cache, then i will load my image from cache
if let imageFromCache = self.objCache.object(forKey: key1){
cell.imgPicture.image = imageFromCache as! UIImage
}
else{//if my image is not in cache ......
if imageData != nil {
let myPicture = UIImage(data: imageData! as Data)
cell.imgPicture.image = myPicture
//save my image in cache
self.objCache.setObject(myPicture!, forKey: ImageString as AnyObject)
}
}
}
}
return cell
}
编辑后的代码 - 版本 II:
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = self.collectionViewPRODUSE.dequeueReusableCell(withReuseIdentifier: "MyCustomCell", for: indexPath) as! clsCustomCell
cell.lblPret.text = vPrice[indexPath.item]
cell.lblTitlu.text = vTitle[indexPath.item]
cell.layer.borderColor = UIColor.lightGray.cgColor
cell.layer.borderWidth = 0.5
let key1 = self.vImages_api[indexPath.item] as AnyObject
if let imageFromCache = self.objCache.object(forKey: key1){
cell.imgPicture.image = imageFromCache as! UIImage
}else{
DispatchQueue.global(qos: .background).async {
let ImageString = self.vImages_api[indexPath.item]
let imageUrl = URL(string: ImageString)
let imageData = NSData(contentsOf: imageUrl!)
let myPicture = UIImage(data: imageData! as Data)
self.objCache.setObject(poza!, forKey: ImageString as AnyObject)
DispatchQueue.main.async {
if imageData != nil {
cell.imgPicture.image = myPicture
}
}
}
}
return cell
}
编辑后的代码 - 版本 III
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = self.collectionViewPRODUSE.dequeueReusableCell(withReuseIdentifier: "celula_custom", for: indexPath) as! clsCustomCell
cell.lblPret.text = vPrice[indexPath.item]
cell.lblTitlu.text = vTitle[indexPath.item]
NKPlaceholderImage(image: UIImage(named: "loading"), imageView: cell.imgPicture, imgUrl: self.vImages_api[indexPath.item]
) { (image11) in
cell.imgPicture.image = image11
}
cell.layer.borderColor = UIColor.lightGray.cgColor
cell.layer.borderWidth = 0.5
return cell
}