尝试编写一个方便的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封装?

最佳答案

根据关于Childhere的文档:
孩子
反射实例结构的元素。可在适当时使用可选标签,例如表示
存储属性或活动枚举事例的,并将用于查找
当字符串传递给子代方法时。
因为镜像中的子类型定义为

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

因此,所有名称都打印为选项。
要获取标签名称,可以使用可选绑定
我做了一些改变,并在操场上尝试过:
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: , ]

嗯…

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

10-12 00:18
查看更多