【问题标题】:Mutating property by its name按名称更改属性
【发布时间】:2015-07-26 17:22:12
【问题描述】:

在反射 API 的帮助下,我得到了我的类型的属性列表。

func inspectedProperties(ignored: [String] = []) -> [Property] {
    var properties = [String]()

    for child in self.children() {
        guard let label = child.label else {
            continue
        }

        properties += [label]
    }

    return properties.filter { !ignored.contains($0) }
}

此函数返回所有属性的名称。

现在我想通过知道它的名称来改变某个属性。

class Fruit {
    private dynamic var name = "Apple"
}

如果我调用Fruit().inspectedProperties(),我将得到以下数组["name"]

但是是否可以改变名为“name”的变量?

【问题讨论】:

    标签: swift reflection ios8 swift2 ios9


    【解决方案1】:

    好的,我找到了一个非常简单的解决方案,但它并不灵活。实际上,您可以使用 KVO 来改变您的数据类型。为此,您的模型应该是 NSObject 的子类,以启用标记为 dynamic 的 KVO 功能和变量。

    附: typealias Property = String

    class Fruit: NSObject {
        private dynamic var name = "Apple"
    }
    

    然后是变异函数。

    func mutateProperty<T>(property: Property) -> T -> () {
        return { value in
            let filtered = self.children().filter { label, value in
                if let label = label where label == property {
                    return true
                }
    
                return false
            }
    
            guard let child = filtered.first else {
                return
            }
    
    
            if let object = self as? NSObject where child.value is T {
                object.setValue(value as? AnyObject, forKey: property)
            }
        }
    }
    

    那就试试吧:

    let fruit = Fruit()
    fruit.mutateProperty("name")("Google")
    print(fruit.name) // "Google"
    

    它可以工作,但如果你想使用值类型而不是引用类型,它就行不通了。可能有一些低级别的解决方案,但我不熟悉一个。如果有人知道怎么做,请在这里留下您的答案! :)

    【讨论】:

    • 对值类型有一些基本支持,但仍然缺少一些支持,例如:可空类型、可空对象数组、枚举和泛型。您可以为此创建解决方法。有关更多信息,请参阅github.com/evermeer/EVReflection 的解决方法部分
    猜你喜欢
    • 2012-01-18
    • 2016-06-24
    • 2023-03-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-24
    • 2017-07-28
    • 1970-01-01
    相关资源
    最近更新 更多