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

添加@MainActor仍无法保证线程安全,UICollectionView重复请求致崩溃

解决方案

核心思路

通过线程安全的加载状态标记避免并发请求,确保同一时间仅一个API请求执行,同时修正数据处理中的潜在问题,从根源上防止DiffableDataSource因重复标识符崩溃。

具体实现步骤

1. 添加原子性加载状态变量

在类中新增@MainActor修饰的布尔变量,保证状态读写均在主队列执行,消除多线程竞态条件:

@MainActor private var isFetching = false

2. 改造updateItems函数,增加请求拦截逻辑

发起API请求前先校验加载状态,若已有请求在执行则直接返回;通过defer确保请求结束后重置状态:

@MainActor
internal func updateItems() async throws {
    guard !isFetching else { return }
    isFetching = true
    defer { isFetching = false }
    
    let newItems = try await NetworkService.shared.getItems(limit: 10, cursor: cursor)
    guard !newItems.isEmpty else { return }
    
    self.cursor = newItems.last
    // 修正原代码语法错误:newItems(\.id) 应为 map 调用
    let newIDs = newItems.map(\.id)
    // 可选:过滤重复ID,进一步避免DiffableDataSource崩溃
    let uniqueIDs = newIDs.filter { !self.itemIDs.contains($0) }
    let uniqueItems = newItems.filter { uniqueIDs.contains($0.id) }
    
    self.items.append(contentsOf: uniqueItems)
    self.itemIDs.append(contentsOf: uniqueIDs)
    
    self.buildSnapshot()
}

3. 优化willDisplay方法,前置状态校验

触发加载前先检查是否正在请求,避免重复创建Task发起并行请求:

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    guard !isFetching else { return }
    if (self.itemIDs.count - indexPath.row) < 5 {
        Task(priority: .userInitiated) {
            try await self.updateItems()
        }
    }
}

4. 改进快照构建逻辑(可选)

基于现有快照增量更新,而非全量重建,提升性能:

@MainActor
func buildSnapshot() {
    var snapshot = dataSource.snapshot()
    if snapshot.sectionIdentifiers.isEmpty {
        snapshot.appendSections([.allItems])
    }
    snapshot.appendItems(self.items)
    dataSource.apply(snapshot, animatingDifferences: true)
}

关键说明

  • @MainActor修饰的isFetching是解决问题的核心:之前使用状态标记无效,大概率是因为未保证状态读写的原子性,主队列下的状态操作能彻底避免并发冲突。
  • defer语句确保无论请求成功、失败还是抛出异常,加载状态都会被重置,不会阻塞后续的加载触发。
  • 新增的重复ID过滤逻辑,即使出现极端情况的重复请求,也能避免DiffableDataSource因重复标识符崩溃。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 08:05:12