如何使用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实例的属性名称和值?

这是我正在尝试的:

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,使用反射,但到目前为止,我无法获得实例的属性名称和值。

文档说:

可选标签可以在适当的时候使用,例如,表示存储属性的名称或活动枚举情况,并将在字符串传递给后代方法时用于查找。

但是我只得到一个"Some"字符串。

另外,当我期望每个子节点都是"反映实例结构的元素"时,值属性返回一个类型为RSS2FeedChannel的字符串!

当我理解正确,这应该解决你的问题:

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
}

只是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
}

您可以在Mirror对象上使用descendent方法来获取此信息。如果未找到值或可选项不包含值,则返回nil。

let mirror = Mirror(reflecting: feed.channel)
let child1 = mirror.descendant("Some", "title") // "The Channel Title"
// or on one line
let child3 = Mirror(reflecting: feed).descendant("channel", "Some", "title")

相关内容

  • 没有找到相关文章

最新更新