如何使用Swift 2.0和反射获取属性名称及其值?
给出此模型:
public class RSS2Feed {
public var channel: RSS2FeedChannel?
public init() {}
}
public class RSS2FeedChannel {
public var title: String?
public var description: String?
public init() {}
}
我需要做什么才能获取RSS2FeedChannel
实例的属性名称和值?
What would I need to do in order to get the property names and values of an RSS2FeedChannel
instance?
这就是我要尝试的:
let feed = RSS2Feed()
feed.channel = RSS2FeedChannel()
feed.channel?.title = "The Channel Title"
let mirror = Mirror(reflecting: feed.channel)
mirror.children.first // ({Some "Some"}, {{Some "The Channel Title...
for (index, value) in mirror.children.enumerate() {
index // 0
value.label // "Some"
value.value // RSS2FeedChannel
}
最终,我正在尝试使用反射创建一个与实例匹配的Dictionary
,但是到目前为止,我无法获得实例的属性名称和值.
Ultimately, I'm trying to create a Dictionary
that matches the instance, using reflection, but so far I'm unable to get the properties name and values of the instance.
文档说:
在适当的时候可以使用可选标签,例如表示存储属性或活动枚举大小写的名称,当将字符串传递给后代方法时将用于查找.
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.
但是我只得到一个"Some"字符串.
Yet I only get a "Some" string.
此外,当我希望每个子对象都是反映实例结构的元素"时,value属性将返回类型为RSS2FeedChannel
的字符串!
Also, the value property is returning a string with the Type RSS2FeedChannel
when I would expect each children to be "An element of the reflected instance's structure."!
当我理解正确时,这应该可以解决您的问题:
When i understand correct this should solve ur problem:
func aMethod() -> Void {
let feed = RSS2Feed()
feed.channel = RSS2FeedChannel()
feed.channel?.title = "The Channel Title"
// feed.channel?.description = "the description of your channel"
guard let channel = feed.channel else {
return
}
let mirror = Mirror(reflecting: channel)
for child in mirror.children {
guard let key = child.label else {
continue
}
let value = child.value
guard let result = self.unwrap(value) else {
continue
}
print("\(key): \(result)")
}
}
private func unwrap(subject: Any) -> Any? {
var value: Any?
let mirrored = Mirror(reflecting:subject)
if mirrored.displayStyle != .Optional {
value = subject
} else if let firstChild = mirrored.children.first {
value = firstChild.value
}
return value
}
快速3进行一些小的更改,
just some little changes for swift 3:
private func unwrap(_ subject: Any) -> Any? {
var value: Any?
let mirrored = Mirror(reflecting:subject)
if mirrored.displayStyle != .optional {
value = subject
} else if let firstChild = mirrored.children.first {
value = firstChild.value
}
return value
}