Exo*_*imp 4 inheritance mirror swift swift2
我需要将我的类的属性作为字典.为简单起见,我创建了一个具有默认实现的协议,如下所示:
protocol ListsProperties{
func toDictionary() -> [String: AnyObject]
}
extension ListsProperties{
func toDictionary() -> [String: AnyObject] {
let mirrored_object = Mirror(reflecting: self)
var dict = [String: AnyObject]()
for (_, attr) in mirrored_object.children.enumerate() {
if let propertyName = attr.label as String! {
dict[propertyName] = attr.value as? AnyObject
}
}
return dict
}
}
Run Code Online (Sandbox Code Playgroud)
我的类可以符合这个协议,并且可以使用toDictionary()方法.但是,如果我在子类上使用该方法,则这不起作用,因为它只会生成在子类上定义的属性并忽略父超类属性.
理想情况下,我可以找到一些方法来调用镜像超类上的toDictionary()方法,因为这会在它自己的超类上调用toDictionary(),并且编译器说超类镜像不符合协议,即使它正在镜像的类确实.
以下工作,但只有当只有一个超类时,这是不够的:
func toDictionary() -> [String: AnyObject] {
let mirrored_object = Mirror(reflecting: self)
var dict = [String: AnyObject]()
for (_, attr) in mirrored_object.children.enumerate() {
if let propertyName = attr.label as String! {
dict[propertyName] = attr.value as? AnyObject
}
}
// This is an issue as it limits to one subclass 'deep'
if let parent = mirrored_object.superclassMirror(){
for (_, attr) in parent.children.enumerate() {
if let propertyName = attr.label as String!{
if dict[propertyName] == nil{
dict[propertyName] = attr.value as? AnyObject
}
}
}
}
return dict
}
Run Code Online (Sandbox Code Playgroud)
关于如何修改toDictionary()的默认实现以包含超类属性(以及超类的任何超类的属性等)的任何想法?
Mar*_*n R 12
一种可能的解决方案是将其toDictionary()
作为Mirror自身的方法实现,以便您可以递归遍历到超类镜像:
extension Mirror {
func toDictionary() -> [String: AnyObject] {
var dict = [String: AnyObject]()
// Properties of this instance:
for attr in self.children {
if let propertyName = attr.label {
dict[propertyName] = attr.value as? AnyObject
}
}
// Add properties of superclass:
if let parent = self.superclassMirror() {
for (propertyName, value) in parent.toDictionary() {
dict[propertyName] = value
}
}
return dict
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用它来实现协议扩展方法:
extension ListsProperties {
func toDictionary() -> [String: AnyObject] {
return Mirror(reflecting: self).toDictionary()
}
}
Run Code Online (Sandbox Code Playgroud)
您可以简单地循环遍历所有superclassMirrors 来获取属性。有多少层并不重要。
var mirror: Mirror? = Mirror(reflecting: child)
repeat {
for property in mirror!.children {
print("property: \(property)")
}
mirror = mirror?.superclassMirror()
} while mirror != nil
| 归档时间: |
|
| 查看次数: |
2364 次 |
| 最近记录: |