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

SwiftUI 单视图中如何发起多个 FetchRequest 获取 Core Data 数据

实现方案

首先澄清一个误区:SwiftUI 没有限制单个视图只能声明一个FetchRequest,你可以根据需求声明多个带不同过滤条件的请求,也可以直接过滤已拉取到的所有上场球员数据,两种方案都可以满足你的需求。


方案1:声明多个独立FetchRequest

直接为不同位置的球员声明对应过滤条件的FetchRequest,拉取结果会自动同步Core Data的数据变更,不需要额外手动维护:

// 拉取所有上场的投手
FetchRequest(
    entity: Player.entity(),
    sortDescriptors: [],
    predicate: NSPredicate(format: "isPlaying == %@ AND Position == %@", true as CVarArg, "P")
)
var pitchers: FetchedResults<Player>

// 拉取所有上场的游击手
FetchRequest(
    entity: Player.entity(),
    sortDescriptors: [],
    predicate: NSPredicate(format: "isPlaying == %@ AND Position == %@", true as CVarArg, "SS")
)
var shortstops: FetchedResults<Player>

// 原有拉取所有上场球员的请求可按需保留
FetchRequest(
    entity: Player.entity(),
    sortDescriptors: [],
    predicate: NSPredicate(format: "isPlaying == %@", true)
)
var allPlayers: FetchedResults<Player>

方案2:过滤现有拉取结果

如果你不想额外增加请求,直接对已拿到的allPlayers做过滤即可,两种实现方式可选:

  1. 用计算属性自动同步更新(不需要手动维护@State,推荐优先用这个)
// 投手数组,自动跟随allPlayers更新
var pitcherList: [Player] {
    allPlayers.filter { $0.Position == "P" }
}

// 游击手数组
var shortstopList: [Player] {
    allPlayers.filter { $0.Position == "SS" }
}
  1. 如果你确实需要将结果存储到@State数组中做后续修改,监听allPlayers的变更同步赋值即可:
@State var pitcherList: [Player] = []
@State var shortstopList: [Player] = []

// 在GameView的body根视图上添加监听
.onChange(of: allPlayers) { newPlayers in
    pitcherList = newPlayers.filter { $0.Position == "P" }
    shortstopList = newPlayers.filter { $0.Position == "SS" }
}

代码优化建议

你现有代码中SetAwayPitcher和SetHomePitcher的9个分支硬编码逻辑可以直接替换,大幅减少冗余代码,示例如下:

// 假设Player实体有标识主客场的属性isHomeTeam,没有的话可以按你自己的归属逻辑替换过滤条件
func setAwayPitcher() {
    guard let awayPitcher = pitcherList.first(where: { !$0.isHomeTeam }) else { return }
    AwayPitcher["FirstName"] = awayPitcher.firstName
    AwayPitcher["LastName"] = awayPitcher.lastName
}

func setHomePitcher() {
    guard let homePitcher = pitcherList.first(where: { $0.isHomeTeam }) else { return }
    HomePitcher["FirstName"] = homePitcher.firstName
    HomePitcher["LastName"] = homePitcher.lastName
}

同时建议遵循Swift的编码规范:变量、函数名使用小驼峰命名(比如gameIsOver而不是GameIsOver,teamNamesAndColors而不是TeamNamesAndColors)。


内容的提问来源于stack exchange,提问作者Manny M.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 22:45:09