UICollection 在使用 Swift 3 显示图像时非常慢
Posted
技术标签:
【中文标题】UICollection 在使用 Swift 3 显示图像时非常慢【英文标题】:UICollection is very slow in showing Image with Swift 3 【发布时间】:2017-03-29 08:31:10 【问题描述】:我正在使用 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)
这是我运行项目时的屏幕截图。我运行时得到了这么多行代码。
请任何人帮助我该怎么办?
【问题讨论】:
显示您的代码,因为您似乎做错了什么。关于从后台线程修改自动布局的错误是明确的,并且已经在 SO 上得到了回答。如果您不显示代码,我们无法猜测在哪里以及为什么。以及为什么要写cell.layer.rasterizationScale = UIScreen.main.scale
。
@Larme,您好,我更新了我的帖子。请复习一下,为什么我写 cell.layer 代码是因为我发现有人写这个代码来解决问题。
【参考方案1】:
当我从 API 调用获取数据并重新加载 UITableView
(根据我的要求)时,我得到了相同的 console error
。我的问题通过使用解决了
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
我之前在控制台上遇到的错误的屏幕截图
【讨论】:
你好兄弟@agent_stack,我也使用这个代码。请检查我更新的问题。我上传我的代码。谢谢。 :) 我试过兄弟@agent_stack。但还是不行。我的过程是我从服务器中提取数据。到达此收藏页面后,拉取过程就完成了。我也查了一下调试区。为了将这些拉取的数据显示到 UIview,它花费了很多时间,并且在调试区域中得到了上述警告。 @MayPhyu bro,如果您的图像提取过程在您的 UICollectionView 中显示之前完成,为什么您再次从 URL 获取图像?? 兄弟 @agent_stack ,我们在服务器中存储了一千张图像,我们一次提取 10 张图像,然后在集合视图中显示它们。之后,我们提取接下来的 10 张图像。 我从 assets 文件夹中获取图像时出现了延迟,例如“img1.jpg”,....,你能给我一些建议吗?【参考方案2】:你可以尝试SDWebimage所有异步线程操作维护良好。
这可以提供以下优点
异步下载
如果应用发生内存警告,则自动清除图像缓存
图片网址缓存
图像缓存
避免重复下载
您可以直接在单元格中使用单个方法,如下所示
[cell.storeImg sd_setImageWithURL:[NSURL URLWithString:strURL] placeholderImage:kDefaultImageForDisplay];
在您的代码中,以下行应该会产生问题,因为该操作可能发生在主线程上 让 data = NSData(contentsOf:url! as URL)
【讨论】:
【参考方案3】:这一行:
DispatchQueue.main.async()
在下载图像时可能会导致错误,它会阻塞主线程并在主(UI)队列上执行网络请求,更不用说这些请求随后会串行执行(因此很慢)。尝试将sn-p更改为:
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 (但是对于表格视图,但您可以轻松地将其扩展为收藏)关于如何实现这一点。
【讨论】:
兄弟@WladekSurala,我使用你的代码。但我得到的错误是“对成员'global(priority:)'的模糊引用”。 @MayPhyu 尝试将此调用替换为 - DispatchQueue.global(qos: DispatchQoS.QoSClass.default).async \\download code here 兄弟@WladekSurala,还是一样。仍然很慢并在命令行中显示以上行。 会有很多行。我从服务器中提取数据。到达此收藏页面后,拉取过程就完成了。我也查了一下调试区。为了将这些拉取的数据显示到 UIview,它花费了很多时间,并且在调试区域中得到了上述警告。以上是关于UICollection 在使用 Swift 3 显示图像时非常慢的主要内容,如果未能解决你的问题,请参考以下文章
如何在 iOS swift 中的 ARSCNView 中显示 uicollection 视图
Swift - 如果项目滚动一点,UICollection 快速恢复
Swift 3 - iOS 11.2上的UICollectionview问题