这是我的代码的简化版本,但我希望能够从通用
NSPredicate
初始化 KeyPath<Root, Value>
,但尽管不断尝试,我还是未能成功。有人可以帮忙吗?
PS:我知道我可以更改方法以采用
key: String
并让调用者在调用站点使用 #keypath(Object.property)
,但我不想这样做,因为我想强制使用 KeyPath 来确保编译安全.
func makeNSPredicate<Root, Value>(keyPath: KeyPath<Root,Value>, value: Value) -> NSPredicate {
NSPredicate(format: "%K == '\(value)'", argumentArray: [keyPath])
}
运行时错误:信号 SIGABRT
func makeNSPredicate<Root, Value>(keyPath: KeyPath<Root,Value>, value: Value) -> NSPredicate {
NSPredicate(format: "%K == '\(value)'", keyPath)
}
编译错误:参数类型“KeyPath
”不符合预期类型“CVarArg”
func makeNSPredicate<Root, Value>(keyPath: KeyPath<Root,Value>, value: Value) -> NSPredicate {
NSPredicate(format: "%K == '\(value)'", #keyPath(keyPath))
}
编译错误:'#keyPath'的参数引用非'@objc'属性'keyPath'
Predicate
转换为 NSPredicate
。这不适用于 every Predicate
,但假设您正在比较 Objective-C 可见的关键路径,并且它们的值也可以在 Objective-C 中表示,那么这是可行的。
func makeNSPredicate<Root: NSObject, Value: Equatable & Codable>(keyPath: KeyPath<Root,Value>, value: Value) -> NSPredicate {
NSPredicate(Predicate<Root> { x in
PredicateExpressions.build_Equal(
lhs: PredicateExpressions.build_KeyPath(
root: PredicateExpressions.build_Arg(x),
keyPath: keyPath
),
rhs: PredicateExpressions.build_Arg(value)
)
})!
}
虽然
Predicate
经常在 SwiftData 上下文中使用,但您不需要导入 SwiftData 来使用它。它实际上是基金会的一部分。
请注意,此处的
Value
需要为 Codable
,因此您可能必须为您要比较的某些类型实现 Codable
。