Swift 3 反射 - 迭代属性

标签 swift reflection swift3

尝试编写一个方便的 toString() 方法来列出一个对象的所有属性及其分配的值。

class FooModel
{
    func toString() -> String
    {
        var result = "[\(String(describing: type(of: self))) "
        let mirror = Mirror(reflecting: self)
        mirror.children.forEach
        {
            child in
                result += "\(child.label): \(child.value), "
        }
        return "\(result)]"
    }
}

class FooProject : FooModel
{
    var id = 0
    var name = ""
    var announcement:String?
    var showAnnouncement = false
    var isCompleted = false
    var completedOn:String?
    var suiteMode = 0
    var url = ""
}

输出:

[FooProject Optional("id"): 0, Optional("name"): , Optional("announcement"): nil, Optional("showAnnouncement"): false, Optional("isCompleted"): false, Optional("completedOn"): nil, Optional("suiteMode"): 0, Optional("url"): , ]

首先,它没有列出实际值,而是列出了默认值。这是为什么? 第二,有没有办法摆脱Optional封装?

最佳答案

根据关于 Child 的文档 here :

child

An element of the reflected instance’s structure. The optional label may be used when appropriate, e.g. to represent the name of a stored property or of an active enum case, and will be used for lookup when Strings are passed to the descendant method.

因为镜像中的 type child 被定义为

typealias Child = (label: String?, value: Any)

因此所有名称都打印为可选。

要获取标签名称,您可以使用可选绑定(bind)

我做了一些修改并在 playground 中尝试了这个:

class FooModel
{
    func toString() -> String
    {
        var result = "[\(String(describing: type(of: self))) "
        let mirror = Mirror(reflecting: self)
        mirror.children.forEach
            {
                child in
                print(child)
                if let label = child.label {
                    result += "\(label): \(child.value), "
                }
        }
        return "\(result)]"
    }
}

class FooProject : FooModel
{
    var id = 0
    var name = ""
    var announcement:String!
    var showAnnouncement = false
    var isCompleted = false
    var completedOn:String!
    var suiteMode = 0
    var url = ""

    init(id: Int, name: String, completedOn: String) {
        self.completedOn = completedOn
        self.id = id
        self.name = name
        //...
    }
}

let fooProj = FooProject(id: 10, name: "Name", completedOn: "Sunday")
print(fooProj.toString())

输出是:

[FooProject id: 10, name: Name, announcement: nil, showAnnouncement: false, isCompleted: false, completedOn: Sunday, suiteMode: 0, url: , ]

HTH..

关于Swift 3 反射 - 迭代属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46107334/

相关文章:

swift - 使用蒙版从 UIView 中切出一个圆圈

.net - 如何判断 Type 是否实现了 IList<>?

ios - UITableView 不会显示删除按钮

Swift,父类(super class)中定义的函数,当从子类对象调用时返回子类的类名

ios - 我是否必须添加我在 ios8 应用程序中使用的所有框架?

ios - 出于安全原因,如何在iOS中从内存中删除字符串?甚至需要它还是iOS自己处理

Java合成方法与桥接方法混淆

c# - 如何在 C# 中的运行时加载程序集及其所有依赖项以进行反射?

Swift 3 pdf 文件下载不起作用

ios - 在自定义 UIGestureRecognizer 类中调用 self.init 之前使用的 self