我尝试构建一些NestedView,它在视图内部加载视图...取决于对象树。所以我在Playground做了一个简短的测试:
class First {}
class Second:First {}
class Dodd {
func takeIt<Foo, Bar>(content:[Foo], type: Bar.Type) {
print (Foo.self, Bar.self)
print (content as? [Bar] ?? [])
}
}
let arrayOfFirst:[First] = [First()]
let arrayOfSecond:[Second] = [Second(), Second(), Second()]
let dodd = Dodd()
let firstType = First.self
let secondType = Second.self
dodd.takeIt(content: arrayOfSecond, type: firstType)
dodd.takeIt(content: arrayOfFirst, type: secondType)
它产生了良好且可预测的输出:
Second First
[__lldb_expr_77.Second, __lldb_expr_77.Second, __lldb_expr_77.Second]
First Second
[]
大。 但是,如果我尝试在更复杂的环境中使用完全相同的机制,结果就不那么令人满意了。 这是一些ViewController的功能,无论如何:
func addSubviews<HeadType>(for content:[HeadType]) {
Swift.print("ADD SUBVIEW FOR \(HeadType.self)")
func takeNext <ParentType, ChildType>(
parentArray: [ParentType],
pathToChild: AnyKeyPath,
type: ChildType.Type?) -> [ChildType]
{
Swift.print ("\nInside takeNext Child Type <\(ChildType.self)>\n")
let result:[ChildType] = parentArray.flatMap { ( parentElement ) -> ChildType? in
parentElement [keyPath:pathToChild] as? ChildType}
return result
}
let interfaceHead = InterfaceElements(type: HeadType.self)
Swift.print ("\tParentArrayContent: \(HeadType.self) ")
for (label, path) in interfaceHead.paths {
if let firstObject = content.first, let objectAtKeyPath = firstObject[ keyPath:path ] {
Swift.print ("\t\tpath: \(path)")
Swift.print ("\t\ttype: \(InterfaceElements(element: objectAtKeyPath).type.self)")
Swift.print("\t\tLabel", label)
let childType = InterfaceElements(element: objectAtKeyPath).type
let elements = takeNext(
parentArray: content,
pathToChild: path,
type: childType)
let controller = NestedStackViewController(for: elements)
}
}
}
输出:
ADD SUBVIEW FOR Joint
ParentArrayContent: Joint
path: Swift.ReferenceWritableKeyPath<HyperGlyph.Joint, Swift.ImplicitlyUnwrappedOptional<HyperGlyph.Position>>
type: Optional(HyperGlyph.Position)
Label position
Inside takeNext Child Type <NSManagedObject>
ADD SUBVIEW FOR NSManagedObject
ParentArrayContent: NSManagedObject
inited NestedStack for NSManagedObject
inited NestedStack for Joint
第一个循环很好,Joint是Joint,找到了Position类型,发送到takeNext,但是在takeNext函数里面的位置变成了NSManagedObject类型。哪里可以欺骗?
答案 0 :(得分:0)
只有一种方法是明确传递一种类型。
let elements = takeNext(
parentArray: content,
pathToChild: path,
type: SomeType.self) // << Here.
它使程序更复杂,更switch
es,但它现在以强大的方式工作。