用它的名字改变 属性

Mutating property by its name

在反射 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([=11=]) }
}

此函数 returns 为我提供所有属性的名称。

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

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

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

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

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

P.S。 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"

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