swift - 如何从另一个线程提供图像?

标签 swift multithreading

我有一个获取用户图片的代码:

if let photoURL = message[Constants.MessageFields.photoURL], let URL = URL(string: photoURL),
    let data = try? Data(contentsOf: URL) {
    cell.userPic.image = UIImage(data: data)
}

当我使用它时,tableView 在滚动时滞后。

请帮我把这段代码放在另一个线程中。

最佳答案

这是 Apple 提供的一个很好的示例,您可以根据自己的需要进行调整:

Prefetching collection view data

基本思想是为您的图像创建 AsyncFetcher 并将图像创建代码放到单独的操作中。

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: Cell.reuseIdentifier, for: indexPath) as? Cell else {
        fatalError("Expected `\(Cell.self)` type for reuseIdentifier \(Cell.reuseIdentifier). Check the configuration in Main.storyboard.")
    }

    let model = models[indexPath.row]
    let id = model.id
    cell.representedId = id

    // Check if the `asyncFetcher` has already fetched data for the specified identifier.
    if let fetchedData = asyncFetcher.fetchedData(for: id) {
        // The data has already been fetched and cached; use it to configure the cell.
        cell.configure(with: fetchedData)
    } else {
        // There is no data available; clear the cell until we've fetched data.
        cell.configure(with: nil)

        // Ask the `asyncFetcher` to fetch data for the specified identifier.
        asyncFetcher.fetchAsync(id) { fetchedData in
            DispatchQueue.main.async {
                /*
                 The `asyncFetcher` has fetched data for the identifier. Before
                 updating the cell, check if it has been recycled by the
                 collection view to represent other data.
                 */
                guard cell.representedId == id else { return }

                // Configure the cell with the fetched image.
                cell.configure(with: fetchedData)
            }
        }
    }

    return cell
}

但在您的情况下,您应该使用 Table View prefetching

我可以确认这种方法是有效的,并且(如果正确完成)会产生平滑的滚动和良好的用户体验

关于swift - 如何从另一个线程提供图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53407646/

相关文章:

swift - 无法连接两个字典

c - 多线程程序额外运行while循环次数

java - 关于java线程生命周期

android - 需要帮助将进程从 Java(android) 转换为 IOS Swift

ios - 如何通过加密保护文档目录中的数据?

Swift 4,同时访问元组成员作为 inout

java - 多线程与单线程

c# - 使用 timeBeginPeriod/Task 调度时的 Thread.Sleep 与 Task.Delay

java - 管理使用 Java 访问数据库的线程

ios - 如何使用 Kingfisher 仅在磁盘中缓存图像?