如何让completion Handler内代码在UICollectionViewCell初始化前执行
问题原因
网络请求fetchNewsData是异步执行的,发起请求后不会阻塞主线程等待结果返回,所以viewDidLoad里的执行顺序是:
- 触发网络请求
- 立刻执行请求外的
collectionView.reloadData(),此时newsArray还是空数组,CollectionView开始调用数据源方法初始化Cell - 后续网络请求成功返回后,才会执行completion回调里的代码填充
newsArray
另外你在cellForItemAt方法里调用collectionView.reloadData()属于严重错误:每次Cell生成都会触发CollectionView全局刷新,会无限循环调用数据源方法,造成性能问题甚至崩溃。
修复方案
你需要修改3个核心点:
- 把
collectionView.reloadData()移到网络请求的completion回调末尾,且所有UI操作必须切换到主线程执行 - 不要写死返回10个Item,数量和
newsArray的长度绑定,避免数组越界崩溃 - 删除
cellForItemAt里的刷新代码
修改后完整代码
class NewsViewController: UIViewController { let networkManager = NetworkManager() var newsArray = [NewsModel]() var totalResult:Int = 0 @IBOutlet weak var collectionView: UICollectionView! override func viewDidLoad() { super.viewDidLoad() // 若未在Storyboard中设置,需手动绑定delegate和dataSource collectionView.delegate = self collectionView.dataSource = self networkManager.fetchNewsData(forCoutry: "us", category: "business") { newsDataModel in self.totalResult = newsDataModel.totalResults for article in newsDataModel.articles { let news = NewsModel(newsTitle: article.title, urlToNewsWebSite: article.url, authorWebSiteName: article.source.name, urlToImage: article.urlToImage ?? "" ) self.newsArray.append(news) } // 网络请求回调默认在子线程,UI操作必须切到主线程执行 DispatchQueue.main.async { self.collectionView.reloadData() } } } } extension NewsViewController: UICollectionViewDelegate { } extension NewsViewController: UICollectionViewDataSource { func numberOfSections(in collectionView: UICollectionView) -> Int { return 1 } func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { // 数量和数组长度绑定,请求未返回时显示0个Cell,避免数组越界 return newsArray.count } func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "item", for: indexPath) as! NewsCell cell.configureCell() cell.initData(news: newsArray[indexPath.item]) return cell } }
内容的提问来源于stack exchange,提问作者Resly34
相关产品推荐
相关产品推荐

