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

iOS使用Imgur API获取JSON数组赋值后为空 如何解决

问题原因

你的问题核心是异步网络请求的时序逻辑错误:URLSession发起的网络请求是后台异步执行的,调用fetchImages()方法时,网络请求还未完成,方法就已经把初始的空数组返回了。后续请求完成给self.images赋值时,之前的返回逻辑已经执行完毕,所以你拿到的永远是空数组。

另外你在UICollectionView的数据源方法里调用网络请求的逻辑也是错误的,该方法会在列表刷新时频繁触发,会导致大量重复请求。

修改方案

1. 调整ViewModel逻辑

去掉fetchImages的同步返回值,改用回调通知数据更新:

class ImageViewModel {
    private let service = Service()
    var images = [Image]()
    
    func fetchImages(completion: @escaping () -> Void) {
        service.fetchImages { [weak self] images in
            guard let self = self, let images = images else {
                completion()
                return
            }
            self.images = images
            completion()
        }
    }
}

2. 调整ViewController逻辑

在页面生命周期方法中发起请求,数据更新后切主线程刷新列表:

override func viewDidLoad() {
    super.viewDidLoad()
    // 其他页面初始化逻辑
    viewModel.fetchImages { [weak self] in
        DispatchQueue.main.async {
            self?.collectionView.reloadData()
        }
    }
}

数据源方法直接读取本地存储的数组即可:

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    return viewModel.images.count
}

注意事项

  • 异步操作不能通过同步返回的方式获取结果,需要通过回调、代理、响应式框架(如Combine)等方式接收结果
  • 不要在列表数据源回调方法中执行网络请求、耗时操作,避免性能问题和重复请求
  • 所有UI相关操作必须在主线程执行,网络请求默认回调在后台线程,刷新UI前需要切换到主线程

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 13:45:04