在Swift 3上镜像不拾取基类

时间:2017-05-05 19:42:30

标签: swift reflection

我正在构建一个函数,该函数将获取类对象的实例并将其转换为XML请求以发送到Web服务。为了实现这一点,我使用镜像来迭代类中的键/值对。在我的测试中,我发现它工作得很好,有一个主要问题,没有任何继承的类参数。例如,在下面的代码中,循环执行三次for" descriptionText,modelNumber和serialNumber,name和uuid从不收集。有没有办法让我使用镜像并获取基类的所有参数,以及小部件?此外,如果有更好的方法,我会全力以赴。

import UIKit

class BaseObject: NSObject { 
   var name = String()
   var uuid = String()
}

class Widget: BaseObject {
    var descriptionText = String()
    var modelNumber = String()
    var serialNumber = String()
}

var widget1 = Widget()

widget1.name = "Generic Widget"
widget1.uuid = "A guid"
widget1.descriptionText = "Class A Extra Larget Widget"
widget1.modelNumber = "1234"
widget1.serialNumber = "4321"

let widgetMirror = Mirror(reflecting: widget1)

for attr in widgetMirror.children {
    print(attr.label!)
}

2 个答案:

答案 0 :(得分:1)

您需要使用superclassMirror: Mirror?属性。例如:

for attr in widgetMirror.superclassMirror!.children {
    print(attr.label!)
}

打印预期结果:

  


  UUID

<强>更新即可。如果您继续遇到此问题,请将此Mirror 扩展名添加到您的工具包中:

extension Mirror {
    var allChildren: [Mirror.Child] {
        var allChildren: [Mirror.Child] = []
        var mirror: Mirror! = self
        repeat {
            allChildren.append(contentsOf: mirror.children)
            mirror = mirror.superclassMirror
        } while mirror != nil
        return allChildren
    }
}

用法:

for attr in widgetMirror.allChildren {
    print(attr.label!)
}

答案 1 :(得分:1)

已经发布了部分答案,但这是一种将所有内容包装起来的方法。

var mirror: Mirror? = Mirror(reflecting: widget1)

repeat {
    for (index, child) in mirror!.children.enumerated() {
        print (child.label!)
    }

    mirror = mirror?.superclassMirror
} while mirror != nil

我想了一下。我认为这更像是Swifty。

extension Mirror {

    var posterity: Children {
        if let superclassMirror = superclassMirror {
            return Children([children, superclassMirror.posterity].joined())
        } else {
            return children
        }
    }

}

let widgetMirror = Mirror(reflecting: widget1)

for child in widgetMirror.posterity {
    print(child.label!)
}