> On Aug 30, 2017, at 11:17 AM, Joanna Carter via swift-users > <swift-users@swift.org> wrote: > > Hi Kenny > >> Just curious, and because I have a distinct lack of imagination: can you >> share a concrete case of this pattern?
This is likely due to the runtime not handling cycles properly in type metadata initialization—a subclass T needs its base class metadata for BaseObject<T>, which in turn needs the metadata for T to instantiate the generic type. This is something we plan to fix next year since it requires runtime ABI changes. For the particular pattern you've described: > class BaseObject<rootType> > { > private let properties: [PartialKeyPath<rootType> : AnyProperty] > > init(properties: [PartialKeyPath<rootType> : AnyProperty]) > { > self.properties = properties > } > > func value<valueType>(for keyPath: KeyPath<rootType, valueType>) -> > valueType? > { > guard let property = properties[keyPath] else > { > return nil > } > > return property.getValue() > } > > func set<valueType>(value: valueType?, for keyPath: KeyPath<rootType, > valueType>) > { > guard let property = properties[keyPath] else > { > return > } > > property.set(value: value) > } > } > > class Test : BaseObject<Test> > { > var name: String? > { > get > { > return value(for: \.name)! > } > set > { > set(value: newValue, for: \.name) > } > } > > var number: Int? > { > get > { > return value(for: \.number)! > } > set > { > set(value: newValue, for: \.number) > } > } > > init() > { > super.init(properties: [\Test.name : Property<String>(), \Test.number : > Property<Int>()]) > } > } > > Without the generic rootType parameter, all the getter and setter methods > need an explicit mention of the derived class for the keypath : > > class Test : BaseObject > { > var name: String? > { > get > { > return value(for: \Test.name)! > } > set > { > set(value: newValue, for: \Test.name) > } > } > > … > } Would a protocol-based approach suffice? `Self` in a protocol extension would give you access to the concrete type in a similar way: protocol Base: AnyObject { var properties: [PartialKeyPath<Self> : AnyProperty] { get } } extension Base { func value<T>(for keyPath: KeyPath<Self, T>) -> T? { guard let property = properties[keyPath] else { return nil } return property.getValue() } /*etc.*/ } class Test: Base { let properties = [\Test.name: Property<String>()] var name: String { get { return value(for: \.name) } set { set(value: newValue, for: \.name) } } } -Joe _______________________________________________ swift-users mailing list swift-users@swift.org https://lists.swift.org/mailman/listinfo/swift-users