在Swift中追加两个键路径

时间:2018-07-29 09:19:30

标签: swift

我正在尝试在Swift(4)中追加两个KeyPath,但是编译器要么不允许我执行,要么尽管是有效的密钥路径,结果还是为“ nil”。

课程:

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类型的正确组合才能实现此目的?

1 个答案:

答案 0 :(得分:2)

首先要使用Swift 4键路径,不需要对象就可以从NSObject继承(甚至不是类),并且具有KVC兼容属性。

所有NSObject中的第二个类似于AnyObject,但是Swift 4的关键路径需要具体的静态类型。

最后,属性source是可选的,因此您必须解开密钥路径才有效。


要连接键路径,第一个键路径的最后一个组件必须与第二个键路径的第一个组件具有相同的类型

这是WWDC 2017 - Session 212: What's new in Foundation

中的 .appending规则

enter image description here

您可以通过这种方式附加关键路径

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)