用它的名字改变 属性
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"
它可以工作,但是如果你想使用值类型而不是引用类型,它就不会工作。可能有一些低级别的解决方案,但我不熟悉其中一个。如果有人知道怎么做,请在这里留下您的答案! :)
在反射 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"
它可以工作,但是如果你想使用值类型而不是引用类型,它就不会工作。可能有一些低级别的解决方案,但我不熟悉其中一个。如果有人知道怎么做,请在这里留下您的答案! :)