每当我在 Xcode 上测试我的应用程序时,它都能完美运行。然而,下载 Xcode 版本时,当选择另一个类别时,两个类别的视频会混合在一起。这种情况通常发生在切换类别时的前几篇帖子中,有些帖子也会在稍后出现。我在 xcode 和 testflight 上测试了多次,这个问题只出现在 testflight 版本上。无论我如何分隔类别,或者如果我对视频使用 @Published 变量和 @StateObject,似乎都没有任何变化。感谢您提前提供任何帮助!
enum Tab: String {
case categoryOne
case categoryTwo
var title: String {
switch self {
case .categoryOne:
return "Category One"
case .categoryTwo:
return "Category Two"
}
}
}
struct MainView: View {
@State private var selectedTab: Tab = .categoryOne
@State private var categoryOneVideos: [Video] = []
@State private var categoryTwoVideos: [Video] = []
@State private var isLoadingMore = false
@State private var dataReloaded = false
private func loadInitialVideos() {
switch selectedTab {
case .categoryOne:
let allVideos = API.getVideos(category: .categoryOne)
categoryOneVideos = allVideos
.filter { video in
guard let _ = URL(string: video.url.absoluteString) else { return false }
return true
}
.map { $0 }
case .categoryTwo:
let allVideos = API.getVideos(category: .categoryTwo)
categoryTwoVideos = allVideos
.filter { video in
guard let _ = URL(string: video.url.absoluteString) else { return false }
return true
}
.map { $0 }
}
dataReloaded.toggle()
}
private func loadMoreVideos() async {
guard !isLoadingMore else { return }
isLoadingMore = true
await Task.detached(priority: .background) {
var newVideos: [Video] = []
switch selectedTab {
case .categoryOne:
let currentIds = categoryOneVideos.map { $0.id }
if let newMedia = API.getNextMedia(category: .categoryOne, hasSeen: currentIds) {
API.updateMedia(with: newMedia)
newVideos = API.getVideos(category: .categoryOne)
.filter { video in
guard let _ = URL(string: video.url.absoluteString) else { return false }
return true
}
.filter { !currentIds.contains($0.id) }
}
case .categoryTwo:
let currentIds = categoryTwoVideos.map { $0.id }
if let newMedia = API.getNextMedia(category: .categoryTwo, hasSeen: currentIds) {
API.updateMedia(with: newMedia)
newVideos = API.getVideos(category: .categoryTwo)
.filter { video in
guard let _ = URL(string: video.url.absoluteString) else { return false }
return true
}
.filter { !currentIds.contains($0.id) }
}
}
await MainActor.run {
if selectedTab == .categoryOne {
categoryOneVideos.append(contentsOf: newVideos)
} else {
categoryTwoVideos.append(contentsOf: newVideos)
}
isLoadingMore = false
}
}
}
}
.onChange(of: selectedTab) { _ in
let impactMed = UIImpactFeedbackGenerator(style: .medium)
impactMed.impactOccurred()
Task {
loadMoreVideos()
let savedIndex = restoreScrollPosition()
currentIndex = savedIndex
proxy.scrollTo(currentIndex, anchor: .top)
dataReloaded.toggle()
}
}
看起来你在这里有竞争条件。如果我理解正确的话,就会发生这种情况:
onChange
正在使用选项卡 AloadMoreVideos
启动分离任务onChange
再次被调用(使用选项卡 B)await MainActor.run
正在运行,但 (2) 中的 onChange
已将 selectedTab
更改为 B,因此 (1) 中的 loadMoreVideos 的结果被添加到错误的选项卡中。您应该向
loadMoreVideos
“选择的选项卡、要加载的选项卡以及存储结果的位置”添加一个参数