Dynamic 在Swift中,如何使用setValueForKey设置对象的textAlignment属性?

Dynamic 在Swift中,如何使用setValueForKey设置对象的textAlignment属性?,dynamic,reflection,swift,Dynamic,Reflection,Swift,假设我们定义这样一个对象: let object: AnyObject = { var result = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 50)) result.text = "First Text" result.backgroundColor = UIColor.blueColor() return result }() (object as UILabel).text = "S

假设我们定义这样一个对象:

let object: AnyObject = {

    var result = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 50))
    result.text = "First Text"
    result.backgroundColor = UIColor.blueColor()

    return result
}()
(object as UILabel).text = "Second Text"
object.setValue(NSTextAlignment.Center, forKey: "textAlignment")
对于这个例子,我显式地创建了一个
UILabel
,但是在我的实际项目中,我不知道创建了什么类型的对象,所以对于这个例子,我只是将结果视为
AnyObject
。该对象只是一个标准的UILabel,蓝色背景上有“第一个文本”的文本,默认向左对齐

在本例中,我知道该对象实际上是一个
UILabel
,因此我知道可以像这样更改其属性:

let object: AnyObject = {

    var result = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 50))
    result.text = "First Text"
    result.backgroundColor = UIColor.blueColor()

    return result
}()
(object as UILabel).text = "Second Text"
object.setValue(NSTextAlignment.Center, forKey: "textAlignment")
现在我改变了文本。但是在我的实际项目中,我不知道我的对象是一个
UILabel
,所以我不能只做
(对象作为UILabel)
,因为它并不总是
UILabel
。我的解决方法是使用
setValueForKey
。使用
respondsToSelector
(本例中未显示)检查我的对象是否有名为“text”的成员后,我可以通过以下方式更改文本:

object.setValue("Third Text", forKey: "text")
现在,如果我想更改对象的
textAlignment
,在检查对象是否确实有名为
textAlignment
的成员后,我想做如下操作:

let object: AnyObject = {

    var result = UILabel(frame: CGRect(x: 0, y: 0, width: 150, height: 50))
    result.text = "First Text"
    result.backgroundColor = UIColor.blueColor()

    return result
}()
(object as UILabel).text = "Second Text"
object.setValue(NSTextAlignment.Center, forKey: "textAlignment")
但这样做会导致错误:

Type 'NSTextAlignment' does not conform to protocol 'AnyObject'
我在尝试设置
帧时遇到了类似的情况,因为它不喜欢
CGRect
类型,但我可以通过将
CGRect
转换为
NSValue
来绕过它。但是,对于
enum
类型,如
NSTextAlignment
,我找不到修复它的方法


有人知道我如何在这里实现我的目标吗?

您必须使用原始值NSTextAlignment.Center.rawValue

 object.setValue(NSTextAlignment.Center.rawValue, forKey: "textAlignment")

必须使用原始值NSTextAlignment.Center.rawValue

 object.setValue(NSTextAlignment.Center.rawValue, forKey: "textAlignment")

另一种选择是声明一个具有您感兴趣的属性的协议,然后扩展您想要使用的类型以采用该协议。如果在这种情况下这样做对您有效,那么它似乎更安全。

另一种选择是使用您感兴趣的属性声明一个协议,然后扩展要使用的类型以采用该协议。在这种情况下,如果这样做对您有效,它似乎更安全。

虽然协议方法似乎更安全,但事实是,我不知道将使用哪些属性,因为我不知道正在使用哪些对象。一切都是在运行时动态发生的,所以我真的无法为属性本身实现任何静态冷。我能做的最远的事情就是实现从动态值(字符串文本)到他们试图设置的属性的任何类型的转换函数。虽然协议方法似乎更安全,但事实是我不知道将使用什么属性,因为我不知道正在使用什么对象。一切都是在运行时动态发生的,所以我真的无法为属性本身实现任何静态冷。我能做的最远的事情就是实现从动态值(字符串文本)到他们试图设置的属性的任何类型的转换函数。这太完美了!我看了rawValue一点,但我没意识到我可以用这个。我试图使用它来调用
NSTextAlignment
,但我又回到了将枚举传递给setValueForKey的位置。这很好用,真是太好了!我看了rawValue一点,但我没意识到我可以用这个。我试图使用它来调用
NSTextAlignment
,但我又回到了将枚举传递给setValueForKey的位置。这很有效。