Swift 2.0 获取镜像父类(super class)属性

标签 swift inheritance swift2 mirror

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

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
    }
}

我的类可以符合此协议(protocol),并且将具有可用的 toDictionary() 方法。但是,如果我在子类上使用该方法,则这不起作用,因为它将仅生成在子类上定义的属性,而忽略父类父类(super class)属性。

理想情况下,我可以找到某种方法在镜像父类(super class)上调用 toDictionary() 方法,因为这将在其自己的父类(super class)上调用 toDictionary() 方法,并且编译器会说父类(super class)镜像不符合协议(protocol),即使该类它是镜像。

以下方法有效,但仅当只有一个父类(super class)时才有效,因此还不够:

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() 的默认实现以包含父类(super class)属性(以及父类(super class)的任何父类(super class)的属性等)有什么想法吗?

最佳答案

一种可能的解决方案是实现toDictionary() 作为Mirror本身的方法,这样就可以递归遍历 到父类(super class)镜像:

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
    }
}

然后用它来实现协议(protocol)扩展方法:

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

关于Swift 2.0 获取镜像父类(super class)属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34308244/

相关文章:

ios - UICollectionViewCell 中的 UICollectionView

ios - 有没有办法获取 UITableViewCell 的 ID?

c++ - 如何修复由多态性引起的错误?

Java继承图

swift - 尝试使用变量更改 SKSpriteNode 图像

ios - Xcode Swift 代码中使用的不同方案中的环境变量

ios - UITableViewCell 按钮不可点击 IOS Swift

ios - 如何使用 AVCaptureVideoPreviewLayer 从相机应用程序实现 2 倍变焦

iOS 13 强制应用显示蓝牙权限提示

c# - oop 检查返回类型是父类还是子类