Swift 2.0获取镜像超类属性 [英] Swift 2.0 Get Mirrored Superclass Properties

查看:111
本文介绍了Swift 2.0获取镜像超类属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要将我的类的属性作为字典。为简单起见,我创建了一个具有默认实现的协议,如下所示:

I need to get the properties of my class as a dictionary. For simplicity, I created a protocol which has a default implementation as follows:

protocol ListsProperties{
    func toDictionary() -> [String: AnyObject]
}

extension ListsProperties{
    func toDictionary() -> [String: AnyObject] {
        let mirrored_object = Mirror(reflecting: self)
        var dict = [String: AnyObject]()
        for (_, attr) in mirrored_object.children.enumerate() {
            if let propertyName = attr.label as String! {
                dict[propertyName] = attr.value as? AnyObject
            }
        }     

        return dict
    }
}

我的类可以符合这个协议,并且可以使用toDictionary()方法。但是,如果我在子类上使用该方法,则不起作用,因为它只生成子类上定义的属性并忽略父超类属性。

My classes can conform to this protocol and will have the toDictionary() method available. However, this does not work if I use the method on a subclass, as it will produce only the properties defined on the subclass and ignore the parent superclass properties.

理想情况下我可以找到一些方法来调用镜像超类上的toDictionary()方法,因为这会在它自己的超类上调用toDictionary(),并且编译器会说超类镜像不符合协议,即使它正在镜像的类也是如此。

Ideally I could find some way to call the toDictionary() method on the mirrored superclass as this would then call toDictionary() on its own superclass and the compiler says that the superclass mirror does not conform to the Protocol even though the class it is mirroring does.

以下情况有效但仅在只有一个超类时才有效:

The following works but only if there is only one superclass so isn't sufficient:

func toDictionary() -> [String: AnyObject] {
    let mirrored_object = Mirror(reflecting: self)
    var dict = [String: AnyObject]()
    for (_, attr) in mirrored_object.children.enumerate() {
        if let propertyName = attr.label as String! {
            dict[propertyName] = attr.value as? AnyObject
        }
    }

    // This is an issue as it limits to one subclass 'deep' 
    if let parent = mirrored_object.superclassMirror(){
        for (_, attr) in parent.children.enumerate() {
            if let propertyName = attr.label as String!{
                if dict[propertyName] == nil{
                    dict[propertyName] = attr.value as? AnyObject
                }
            }
        }
    }

    return dict
}

关于如何修改toDictionary()的默认实现以包含超类属性(以及超类的任何超类的属性等)的任何想法?

Any ideas on how I could modify the default implementation of toDictionary() to include superclass attributes (and the attributes of any superclasses of the superclass etc)?

推荐答案

一种可能的解决方案是实现 toDictionary()
方法镜像本身,这样你就可以递归地遍历
到超类镜像:

One possible solution would be to implement toDictionary() as a method of Mirror itself, so that you can traverse recursively to the superclass mirror:

extension Mirror {

    func toDictionary() -> [String: AnyObject] {
        var dict = [String: AnyObject]()

        // Properties of this instance:
        for attr in self.children {
            if let propertyName = attr.label {
                dict[propertyName] = attr.value as? AnyObject
            }
        } 

        // Add properties of superclass:
        if let parent = self.superclassMirror() {
            for (propertyName, value) in parent.toDictionary() {
                dict[propertyName] = value
            }
        }

        return dict
    }
}

然后使用它来实现协议扩展方法:

and then use that to implement the protocol extension method:

extension ListsProperties {
    func toDictionary() -> [String: AnyObject] {
        return Mirror(reflecting: self).toDictionary()
    }
}

这篇关于Swift 2.0获取镜像超类属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆