You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LPMetadataProvider是一次性对象,CollectionView滚动时报错如何解决?

问题根因

你遇到的报错核心原因是*LPMetadataProvider属于单次使用对象,完成一次元数据请求后就无法再次调用startFetchingMetadata方法*。而CollectionView的单元格会被滚动复用,每次重新赋值previewCell时都会触发fetchPreview,复用同一个全局初始化的provider就会触发报错:

Trying to start fetching on an LPMetadataProvider that has already started. LPMetadataProvider is a one-shot object.

解决方案

你可以按照以下逻辑修改代码,解决复用冲突同时保证能拿到didSet传递的链接参数:

var urlString: String?
// 存储当前请求的链接,用于回调校验避免内容错位
var currentFetchURL: URL?
// provider改为可选类型,方便重用时重置
var provider: LPMetadataProvider?

var previewCell: LinkModel? {
    didSet {
        urlString = previewCell?.linkURL
        fetchPreview()
    }
}

let linkPreview = LPLinkView()

override init(frame: CGRect) {
    super.init(frame: frame)
    contentView.backgroundColor = .black
    // LPLinkView只需要添加一次,不要在请求回调中重复添加
    contentView.addSubview(linkPreview)
    // 适配布局,也可以用frame布局
    linkPreview.frame = contentView.bounds
    linkPreview.autoresizingMask = [.flexibleWidth, .flexibleHeight]
}

// 重写重用方法,清理旧状态
override func prepareForReuse() {
    super.prepareForReuse()
    // 取消未完成的旧请求
    provider?.cancel()
    provider = nil
    // 清空旧预览内容
    linkPreview.metadata = nil
    currentFetchURL = nil
}

fileprivate func fetchPreview() {
    guard let url = URL(string: urlString ?? "") else { return }
    currentFetchURL = url
    // 每次请求创建全新的provider,避免单次使用限制
    let newProvider = LPMetadataProvider()
    self.provider = newProvider
    
    newProvider.startFetchingMetadata(for: url) { [weak self] metaData, error in
        guard let self = self,
              let data = metaData,
              error == nil,
              // 校验链接一致性,避免滚动复用出现内容错位
              self.currentFetchURL == url else {
            return
        }
        DispatchQueue.main.async {
            self.linkPreview.metadata = data
        }
    }
}

核心修改点

  • 每次触发fetchPreview时都创建全新的LPMetadataProvider实例,绕过单次使用的限制
  • 重写prepareForReuse方法,在单元格被复用前取消未完成的旧请求、清空历史状态,避免旧请求返回后更新错误内容
  • 将LPLinkView的添加和布局逻辑移到初始化方法中,避免请求成功后重复添加视图到层级中
  • 增加currentFetchURL校验逻辑,确保回调返回的元数据属于当前单元格需要展示的链接,避免滚动时出现内容错位

内容的提问来源于stack exchange,提问作者SwiftTry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.01 11:39:05