镜像未拾取 Swift 上的 Class 基数 3

Mirroring Not Picking Up Base Class on Swift 3

我正在构建一个函数,它将采用 class 对象的实例并将其转换为要发送到 Web 服务的 XML 请求。为此,我使用镜像遍历 class 中的 key/value 对。在我的测试中,我发现它运行良好,但有一个主要问题,继承的 class 参数中的 none 出现了。比如下面的代码,循环执行了3次“descriptionText,modelNumber和serialNumber,name和uuid都没有收集到。有没有办法让我用镜像把base [=16的所有参数都取出来=],还有小部件?另外,如果有更好的方法来做到这一点,我洗耳恭听。

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

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

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

打印预期结果:

name
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!)
}

已经发布了部分答案,但这里有一个总结的方法。

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