Swift: reflection of protocol variables

让人想犯罪 __ 提交于 2019-12-06 15:00:19

Computed properties are not represented in the runtime introspection provided by Mirror

From the Language Reference - Mirror struct (emphasis added by me)

Representation of the sub-structure and optional "display style" of any arbitrary subject instance.

Describes the parts---such as stored properties, collection elements, tuple elements, or the active enumeration case---that make up a particular instance. May also supply a "display style" property that suggests how this structure might be rendered.

The properties id (int) and isItTrue (bool) are available to instances of MirrorMe, but only as computed properties, as MirrorMe does not implement these as stored properties, but rather, make use of the default implementation of them as computed properties from extension SomeProtocol where Self: SomeClass { ... }. Hence, the computed properties id and isItTrue of MirrorMe are not contained in the sub-structure representation of MirrorMe instances, as provided by runtime introspection using Mirror.

We can verify this clearly in a more minimal example:

class Foo {
    // a stored property
    let representedInIntrospection = 0

    // a computed property
    var notRepresented: Int { return representedInIntrospection }
}

Mirror(reflecting: Foo())
    .children
    .forEach { print($0.label, $0.value) }
        /* Optional("representedInIntrospection") 0 */

To summarize: properties blueprinted in a protocol, with or without an associated default implementation, can never be stored properties on their own (default implementations of blueprinted properties may naturally only contain computed properties). This means that the only properties that are explicitly declared as stored properties in the class/struct that conforms to your protocol will show up when applying runtime introspection of an instance of such a class/struct.

Finally, you never mention the reason as for why you want a dictionary of the stored properties of a class instance, but take care if making use of this a production purpose. Generally, runtime introspection in a type safe language as Swift should only be used for diagnostics and debugging, even if it allows to be used in runtime hacks (e.g. with KVO for classes inheriting from NSObject).

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!