ios - 因此,如何使 DispatchGroup 与 DispatchQueue 一起工作?
问题描述
我有两个 ViewController,第一个用于显示新闻,第二个用于选择将在第一个 VC 中显示的新闻源。这是我用于在 FeedViewController 中获取新闻的代码。
@objc private func fetchData() {
articles = []
let dispatchGroup = DispatchGroup()
for source in MediaSourceManager.shared.getMediaSources(coreDataStack: coreDataStack) {
if source.isSelected {
dispatchGroup.enter()
FeedAPI.shared.getArticles(newsSource: source) { (articles) in
self.articles += articles
dispatchGroup.leave()
}
}
}
dispatchGroup.notify(queue: .main) {
self.feedTableView.reloadData()
}
}
在 getArticles 中,它只是一个 URLSession.shared.dataTask 请求。
在 MediaSourceManager 我有
private let concurrentQueue = DispatchQueue(label: "News.mediaQueue", attributes: .concurrent)
private var unsafeSources: [MediaSource] = []
var safeSources: [MediaSource] {
var mediasCopy: [MediaSource]!
concurrentQueue.sync {
mediasCopy = self.unsafeSources
}
return mediasCopy
}
func changeSourceIsSelected(at index: Int) {
concurrentQueue.async(flags: .barrier) { [weak self] in
guard let self = self else { return }
self.unsafeSources[index].isSelected = !self.unsafeSources[index].isSelected
DispatchQueue.main.async { [weak self] in
self?.postSelectionNotification()
}
}
}
postSelectionNotification 中的代码
private func postSelectionNotification() {
NotificationCenter.default.post(name: .mediaSelectedChanged, object: nil)
}
在 getArticles 中,我将每篇文章的描述从 html 字符串转换为普通字符串,这似乎是一项繁重的任务。因此,我遇到了诸如索引超出范围之类的错误和奇怪的行为,例如我删除的来源的文章仍会显示,如果我在 UI 中快速完成所有操作(选择各种媒体源并快速移动到提要屏幕),就会发生这种情况。我怎样才能解决这个问题?
解决方案
这不是解决这个问题的最佳方法,但我还是会分享我的方法。首先,在 FeedViewController 中,添加一个变量 count 来跟踪正在处理的请求数,以及一个 UIActivityIndicator。确保当您的活动指示器运行时,为 FeedViewController 禁用了 userInteraction。
@objc private func fetchData() {
articles = []
let dispatchGroup = DispatchGroup()
count += 1 // This variable is to keep track of the number of requests being run
if !activityIndicator.isAnimating { activityIndicator.startAnimating() }
for source in MediaSourceManager.shared.getMediaSources(coreDataStack: coreDataStack) {
if source.isSelected {
dispatchGroup.enter()
FeedAPI.shared.getArticles(newsSource: source) { (articles) in
self.articles += articles
dispatchGroup.leave()
}
}
}
dispatchGroup.notify(queue: .main) {
self.count -= 1
if self.count == 0 {
self.activityIndicator.stopAnimating()
self.feedTableView.reloadData()
}
}
}
如果我能想到更好的解决方案,我会更新我的答案。
推荐阅读
- node.js - 尽管路径设置正确并已全局安装,但无法识别任何 node.js 包。然而,NPM 没有给出任何错误
- shopify - Shopify 中的测验
- c++ - 如何初始化指向nullptr c ++的动态指针数组
- c# - NLog 从 .net 到 .net 核心
- node.js - 如何使用 Fixie Socks(Heroku 插件)通过 mongoose 连接到 mongodb
- ms-access - 通过 ADO 使用 Click2Run/SxS MS Access DBMS 时,如何访问数据库对象?
- python - 创建具有重复项的时间序列序列
- android - 如何从扩展 View 的类启动 AnimationDrawable
- typescript - 如何提示打字稿一个字符串在多个索引操作中是一致的
- python - 如何将带有数字的 Python 数据框列导出为带有逗号分隔符的整数,并能够对它们进行求和/除/乘?