我试图在 Swift (4) 中附加两个 KeyPath,但编译器要么不允许我这样做,要么结果是“nil”,尽管它是一个有效的 keypath。
类:
import Foundation
@objcMembers
class Foo: NSObject
{
@objc public dynamic var items = [1, 2, 3]
}
@objcMembers
class Bar: NSObject
{
@objc public dynamic var source: NSObject?
}
示例 1:
let keyPath1 = \Bar.source
let keyPath2 = \Foo.items
keyPath1.appending(path: keyPath2) // error: cannot convert value of type 'ReferenceWritableKeyPath<Foo, [Int]>' to expected argument type 'WritableKeyPath<_, _>' keyPath1.appending(path: keyPath2)
示例 2:
let keyPath1: WritableKeyPath<Bar, NSObject?> = \Bar.source
let keyPath2: ReferenceWritableKeyPath<Foo, [Int]> = \Foo.items
keyPath1.appending(path: keyPath2) // error: ambiguous reference to member 'appending(path:)'
示例 3:
let keyPath1: AnyKeyPath = \Bar.source
let keyPath2: ReferenceWritableKeyPath<Foo, [Int]> = \Foo.items
keyPath1.appending(path: keyPath2) // returns nil
这里的类有意使用 NSObject
类型的可选成员。生成的 keyPath 应该是 source.items
,它在 Foo
的实例上是一个有效的 keyPath。
新的 Swift 4 keyPath 类型的正确组合是什么来完成这项工作?
最佳答案
首先,要使用 Swift 4 键路径,对象不需要继承 NSObject
(甚至不是类)并具有符合 KVC 的属性。
其次 NSObject
类似于 AnyObject
但 Swift 4 关键路径需要具体的静态类型。
最后,属性 source
是可选的,因此您必须解开 key 路径才能生效。
为了能够连接键路径,第一个键路径的最后一个组件必须与第二个键路径的第一个组件具有相同的类型
这是来自 WWDC 2017 - Session 212: What's new in Foundation 的 .appending 规则
您可以通过这种方式附加关键路径
class Foo {
var items = [1, 2, 3]
}
class Bar {
var source: Foo?
}
let bar = Bar()
bar.source = Foo()
let keyPath1 = \Bar.source!
let keyPath2 = \Foo.items
let keyPath = keyPath1.appending(path: keyPath2)
let items = bar[keyPath:keyPath]
print(items)
关于swift - 在 Swift 中附加两个键路径,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51578904/