我使用UICollectionView在我的应用中显示图像
问题是显示图像需要很慢。 50秒后,将显示集合视图中的图像。 :(
当我在谷歌找到解决方案时,他们大多写下面的代码。
但对我来说, 无法正常工作 。
cell.layer.shouldRasterize = true
cell.layer.rasterizationScale = UIScreen.main.scale
和
extension SeeAllCollectionView {
override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
debugPrint("seeAllLIStCell Count \(assetsTable.count)")
return assetsTable.count
}
override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "seeAllListCell", for: indexPath) as! SeeAllPhotoCell
let list = assetsTable[(indexPath as NSIndexPath).row]
var imageName: String? = (list.poster_image_url)
var image: UIImage? = (images_cache[imageName!])
if image != nil {
debugPrint("Yes Image")
cell.imageView.image = image
} else{
debugPrint("NO Image")
cell.imageView.image = nil
DispatchQueue.main.async(){
let url = NSURL(string: list.poster_image_url)
let data = NSData(contentsOf:url! as URL)
var image = UIImage(data: data as! Data)
DispatchQueue.main.async(execute: {() -> Void in
cell.movieTitle.text = list.name
cell.imageView?.image = image
})
self.images_cache[imageName!] = image
}
}
return cell
}
}
// MARK: - UICollectionViewDelegate
extension SeeAllCollectionView {
override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
debugPrint("Selected")
let list = assetsTable[(indexPath as NSIndexPath).row]
debugPrint(list.poster_image_url)
debugPrint(list.name)
prefs.set(list.poster_image_url, forKey: "poster_image_url")
prefs.set(list.name, forKey: "name")
prefs.set(list.assets_id, forKey: "VIDEO_ID")
prefs.set(false, forKey: "FLAG")
let storyboard = UIStoryboard(name: "Main", bundle: nil)
let vc = storyboard.instantiateViewController(withIdentifier: "DetailsChannel") as UIViewController
self.present(vc, animated: true, completion: nil)
}
}
请有人帮我,我该怎么办?
答案 0 :(得分:0)
当我从API调用中获取数据并重新加载console error
时(根据我的要求),我得到了相同的UITableView
。我的问题通过使用
DispatchQueue.global(qos: .background).async { // load data in back ground mode so that main thread can be safed.
let url = NSURL(string: list.poster_image_url)
let data = NSData(contentsOf:url! as URL)
var image = UIImage(data: data as! Data)
DispatchQueue.main.async(execute: {
cell.movieTitle.text = list.name
cell.imageView?.image = image
})
self.images_cache[imageName!] = image
}
我之前在我的控制台上出现的错误的屏幕截图
答案 1 :(得分:0)
这一行:
DispatchQueue.main.async()
下载图像时可能会导致错误,它会阻塞主线程并在主(UI)队列上执行网络请求,更不用说这些请求随后是串行执行的(因此很慢)。尝试将代码段更改为:
DispatchQueue.global.async(qos: DispatchQoS.QoSClass.background){
let url = NSURL(string: list.poster_image_url)
let data = NSData(contentsOf:url! as URL)
var image = UIImage(data: data as! Data)
DispatchQueue.main.async(execute: {() -> Void in
其中global
代表此类网络操作的全局队列默认值。
编辑:除了使用主队列进行网络调用之外,实际上可能存在的问题实际上是为屏幕上当前不可见的行加载了太多图像。如果它们很多并且连接不是那么好,那么最终会有屏幕上单元格的应用程序待处理下载。考虑仅为屏幕上的单元格延迟加载图像 - 并取消不可见的行的下载。在Swift中有一个非常好的tutorial(但是对于表视图,但你可以很容易地扩展它来收集)如何实现这一点。
答案 2 :(得分:0)
您可以尝试SDWebimage保持所有异步线程操作。
这可以提供以下优势
异步下载
如果应用程序发生内存警告,则自动清除图像缓存
图片网址缓存
图像缓存
避免重复下载
您可以直接在单元格中使用单个方法,如下所示
[cell.storeImg sd_setImageWithURL:[NSURL URLWithString:strURL] placeholderImage:kDefaultImageForDisplay];
在你的代码中,后续行应该会产生问题,因为该操作可能发生在主线程上 let data = NSData(contentsOf:url!as URL)