一尘不染

如何在Swift中遍历struct属性?

swift

是否可以在Swift中遍历结构的属性?

我需要在使用许多不同单元格类型的视图控制器中注册单元格重用标识符(单元格组织在不同的nib文件中)。所以我的想法是将所有重用标识符和对应的nib文件作为静态元组属性(reuseID,nibName)放入结构中。但是,如何遍历所有这些元素以将单元格注册到tableView?

我已经尝试过一些东西(请参阅下面的答案)。但是有没有更简单的方法来做到这一点,例如,无需将每个属性都放在数组中?


阅读 1162

收藏
2020-07-07

共1个答案

一尘不染

尽管是老问题,但随着Swift的发展,这个问题有了新的答案。我认为您的方法更适合描述的情况,但是最初的问题是如何遍历struct属性,所以这是我的答案(
适用于类和struct

您可以使用“
镜像结构参考”
。关键是,在调用reflect某个对象之后,您会得到它的“镜像”,这虽然很少,但是仍然很有用。

因此,我们可以轻松声明以下协议,其中key属性的名称和value实际值是:

protocol PropertyLoopable
{
    func allProperties() throws -> [String: Any]
}

当然,我们应该利用新的协议扩展为该协议提供默认实现:

extension PropertyLoopable
{
    func allProperties() throws -> [String: Any] {

        var result: [String: Any] = [:]

        let mirror = Mirror(reflecting: self)

        guard let style = mirror.displayStyle where style == .Struct || style == .Class else {
            //throw some error
            throw NSError(domain: "hris.to", code: 777, userInfo: nil)
        }

        for (labelMaybe, valueMaybe) in mirror.children {
            guard let label = labelMaybe else {
                continue
            }

            result[label] = valueMaybe
        }

        return result
    }
}

因此,现在我们可以遍历 任何 方法的属性classstruct使用此方法。我们只需要将班级标记为即可PropertyLoopable

为了使事物保持静态(如示例中所示),我还将添加一个单例:

struct ReuseID: PropertyLoopable {
    static let instance: ReuseID = ReuseID()
}

无论是否使用单例,我们最终都可以遍历如下属性:

do {
    print(try ReuseID.instance.allProperties())
} catch _ {

}

循环结构属性就是这样。享受迅速;)

2020-07-07