前提描述
在 SwiftUI 中使用 @FetchRequest 时,它的查询条件(如 predicate)在初始化后是不可变的。
例如,我们想要通过修改stockMarket变量,使用@FetchRequest动态查询Core Data数据:
// 当前股市指数
@State private var stockMarket:String = "GSPC"
@FetchRequest(
fetchRequest: {
let request = NSFetchRequest<Yahoo>(entityName: "Yahoo")
// 筛选 Yahoo 中黄金的数据
request.predicate = NSPredicate(format: "symbol == %@", stockMarket) // stockMarket为变量
request.sortDescriptors = [NSSortDescriptor(key: "updateTime", ascending: false)]
return request
}()
) var stockMarkets: FetchedResults<Yahoo>
实际上会报错:
Cannot use instance member 'stockMarket' within property initializer; property initializers run before 'self' is available
这表示无法在@FetchRequest时使用stockMarket变量。
目前 FetchRequest 是静态写死的,NSPredicate只能绑定静态变量:
predicate: NSPredicate(format: "symbol == %@", "GSPC")
如果想要根据变量的数值切换不同的查询条件,就需要将NSFetchRequest封装到方法中实现动态查询。
Core Data动态查询
因为@FetchRequest无法绑定动态变量,因此,我们可以尝试将变量封装到方法中,通过方法获取Core Data对象数组。每次修改变量时,重新调用一遍方法,就可以实现Core Data动态查询功能。
1、创建变量数组
@State private var stockMarkets: [Yahoo] = []
在SwiftUI中,创建一个用于存储的对象数组,不使用 @FetchRequest 查询对象数组。
2、创建查询方法
// 当前股市指数
@State private var stockMarket:String = "GSPC"
func fetchData() {
let request: NSFetchRequest<Yahoo> = Yahoo.fetchRequest()
request.predicate = NSPredicate(format: "symbol == %@", stockMarket)
request.sortDescriptors = [NSSortDescriptor(key: "updateTime", ascending: false)]
do {
stockMarkets = try viewContext.fetch(request)
} catch {
print("❌ Fetch failed: \(error)")
}
}
这里的fetchData是一个自己封装的方法,没有使用@FetchRequest,是因为@FetchRequest是静态的,不能接受@State动态更新的predicate。
将NSFetchRequest封装在方法中,每次都会调用NSPredicate(format: “symbol == %@”, stockMarket) 动态构造查询条件。
然后通过 viewContext.fetch(request) 执行查询;
查询结果存到自定义的stockMarkets变量数组里。
这样就实现了“动态查询”:每次stockMarket改变,就重新fetch一次新的数据。
3、动态变量改变时重新调用查询方法
@State private var stockMarket: String = "GSPC" {
didSet {
fetchData()
}
}
设置didSet方法,每次修改stockMarket变量时,都会重新调用查询方法。
实现效果
每次修改stockMarket变量,都会重新调用fetchData方法,从而实现动态查询。

本文的代码可以从GitHub的股票指数页面中查看:https://github.com/fangjunyu1/ERdepot/blob/main/ERdepot/View/StockIndexView.swift
总结
通过@State存储查询条件 + 自定义 fetchData() + 动态调用 fetch,可以实现Core Data的动态查询逻辑。
相关文章
1、Apple Core Data持久化框架:https://fangjunyu.com/2025/03/30/apple-coredata%e6%8c%81%e4%b9%85%e5%8c%96%e6%a1%86%e6%9e%b6/
2、SwiftUI获取Core Data数据的@FetchRequest:https://fangjunyu.com/2025/03/30/swiftui%e8%8e%b7%e5%8f%96core-data%e6%95%b0%e6%8d%ae%e7%9a%84fetchrequest/
3、Swift UI利用@Query动态切换排序:https://fangjunyu.com/2024/11/08/swift-ui%e5%88%a9%e7%94%a8query%e5%8a%a8%e6%80%81%e5%88%87%e6%8d%a2%e6%8e%92%e5%ba%8f/
4、SwiftUI @Query动态排序扩展篇:传递绑定变量:https://fangjunyu.com/2024/12/12/swiftui-query%e5%8a%a8%e6%80%81%e6%8e%92%e5%ba%8f%e6%89%a9%e5%b1%95%e7%af%87%ef%bc%9a%e4%bc%a0%e9%80%92%e7%bb%91%e5%ae%9a%e5%8f%98%e9%87%8f/