![](/img/trans.png)
[英]How do I delay running a line of code until animations are finished? (DispatchGroup & DispatchQueue)
[英]How do I make DispatchGroup work consequently with 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()
}
}
}
如果我能想到更好的解决方案,我会更新我的答案。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.