可以在Swift中迭代 struct 的属性吗?
我需要在一个视图控制器中注册单元重用标识符,该控制器使用许多不同的单元类型(单元被组织在不同的nib文件中).所以我的 idea 是将所有重用标识符和相应的nib文件作为静态元组属性(reuseID,nibName)放在一个 struct 中.但是,我如何迭代所有单元格,以便在tableView中注册这些单元格呢?
我已经试过了(见下面我的答案).但是,有没有更简单的方法来实现这一点,例如不将每个属性都放在一个数组中?
可以在Swift中迭代 struct 的属性吗?
我需要在一个视图控制器中注册单元重用标识符,该控制器使用许多不同的单元类型(单元被组织在不同的nib文件中).所以我的 idea 是将所有重用标识符和相应的nib文件作为静态元组属性(reuseID,nibName)放在一个 struct 中.但是,我如何迭代所有单元格,以便在tableView中注册这些单元格呢?
我已经试过了(见下面我的答案).但是,有没有更简单的方法来实现这一点,例如不将每个属性都放在一个数组中?
虽然是老问题,但随着快速发展,这个问题有了新的答案.我认为您的方法更适合描述的情况,然而最初的问题是如何迭代 struct 属性,所以这里是我的答案(works both for classes and structs)
你可以用100.关键是,在对某个对象调用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
}
}
现在我们可以用这个方法循环any,class
或struct
的性质.我们只需要给班级打PropertyLoopable
分.
为了保持静态(如示例中所示),我还将添加一个单例:
struct ReuseID: PropertyLoopable {
static let instance: ReuseID = ReuseID()
}
无论是否使用singleton,我们最终都可以循环使用如下属性:
do {
print(try ReuseID.instance.allProperties())
} catch _ {
}
这就是循环 struct 属性.享受Swift ;)