我正在使用Sourcery在模型上生成一些代码,以比预期的方式更动态地使用KeyPath。 为了使用KepPath设置值,您必须将其强制转换为具体类型,因为KeyPath不是协变的。
因此对于像\Item.category
这样的KeyPath(类别为:String?
)来说,具体类型需要看起来像这样
ReferenceWritableKeyPath<Item, String?>
除非使用self[keyPath: someKeyPath]
是正确的类型,否则您不能使用someKeyPath
写一个值。 PartiakKeyPath
和AnyKeyPath
不起作用。
我有一个枚举key
,该枚举的计算得出的变量keyPath
返回了AnyKeyPath
type(of: key.keyPath).valueType
打印为Optional<String>
当我在枚举上调用此方法时
func writeableKeyPath<T>(kt: T) -> ReferenceWritableKeyPath<Item, T?>? {
return self.keyPath as? ReferenceWritableKeyPath<Item, T?>
}
像这样
key.writeableKeyPath(kt: type(of: key.keyPath).valueType)
由于以下原因,返回始终为null:
Could not cast value of type 'Swift.ReferenceWritableKeyPath<SourceryDemo.Item, Swift.Optional<Swift.String>>' (0x10a8a5f88)
to 'Swift.ReferenceWritableKeyPath<SourceryDemo.Item, Swift.Optional<Any.Type>>'
基本上,它不是在推断Swift.Optional<Swift.String>
并将其强制为Swift.Optional<Any.Type>
如果我将方法签名更改为使用T.Type
并传递String.self
,则它可以工作,但是我正在尝试这样做,而在编译时不需要该信息。而且在使用T.Type
type(of:)
func writeableKeyPath<T>(kt: T.Type) -> ReferenceWritableKeyPath<Item, T?>? { ... }
key.writeableKeyPath(kt: String.self)
这只是我正在尝试摆脱的一些额外魔法,因为我已经有以下方法起作用:
func set<T, V: KeyValueEnum>(value: T, forKey key: V)
func value(forKey string: String) -> Any?
我知道NSObject
和@objc
这样的事情是可行的,但是我试图在没有这些的情况下实现这一目标。