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

如何通过枚举属性使用新#Predicate宏进行数据查询?

在Xcode 15 Beta 4中使用#Predicate宏查询Core Data枚举属性的问题

问题背景

使用Xcode 15 Beta 4,尝试通过新的#Predicate宏查询带有枚举属性的Core Data模型时出现编译错误,两种查询写法均失败:

查询写法1

let predicate = #Predicate<ModelA> { $0.type == ModelA.ModelAType.a }

查询写法2

let predicate = #Predicate<ModelA> { $0.type.rawValue == ModelA.ModelAType.a.rawValue }

模型定义

@Model final class ModelA: Codable {
    @Attribute(.unique) var id: Int64 = 0
    enum ModelAType: Int, CaseIterable, Codable { case a = 1, b }
    var type: ModelAType = ModelAType.a
}

报错信息

Type 'ModelA.Type' cannot conform to 'StandardPredicateExpression'
Type 'ModelA.Type' cannot conform to 'PredicateExpression'
Cannot infer key path type from context; consider explicitly specifying a root type

问题原因

这是Xcode 15 Beta阶段的兼容性缺陷:#Predicate宏对Core Data中未显式标记@Attribute的枚举属性解析存在逻辑问题,无法正确推断枚举类型的表达式路径,导致编译错误;即使通过rawValue比较,宏的表达式解析逻辑也会因类型推断失败抛出错误。

解决方案

1. 给枚举属性添加@Attribute标记

修改模型定义,为枚举属性显式添加@Attribute注解,明确告知Core Data该属性需要持久化:

@Model final class ModelA: Codable {
    @Attribute(.unique) var id: Int64 = 0
    enum ModelAType: Int, CaseIterable, Codable { case a = 1, b }
    // 添加@Attribute标记,Core Data会自动映射枚举的rawValue
    @Attribute var type: ModelAType = .a
}

2. 调整#Predicate写法

修改后的模型支持两种正确的查询写法:

  • 直接比较枚举值:
let predicate = #Predicate<ModelA> { $0.type == .a }
// 或显式指定枚举类型
let predicate = #Predicate<ModelA> { $0.type == ModelA.ModelAType.a }
  • 通过rawValue比较(需提前提取目标值,避免宏解析时的类型混淆):
let targetRaw = ModelA.ModelAType.a.rawValue
let predicate = #Predicate<ModelA> { $0.type.rawValue == targetRaw }

3. 临时过渡方案(使用NSPredicate)

如果上述方案仍无法解决,可以暂时使用旧的NSPredicate作为过渡:

let predicate = NSPredicate(format: "type == %d", ModelA.ModelAType.a.rawValue)

说明

该问题属于Xcode 15 Beta版本的bug,苹果后续的Beta版本或正式版应该会修复#Predicate宏对Core Data枚举属性的解析支持。

内容的提问来源于stack exchange,提问作者PerroVerde

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 18:15:09