如何检查一个对象是否有存储的属性?

我需要检查一个对象的类是否有可用于赋值的成员。 假设有一个类:

class MyClass: NSObject { var myVar : AnyObject! // ... } 

我试过这个objC风格,但属性是Swift中的另一个野兽,第二行始终返回false:

 let myClass: MyClass = MyClass() let hasClassMember = myClass.respondsToSelector(Selector("setMyVar:")) if hasClassMember { myClass.performSelector("setMyVar:", withObject: "Context" as! AnyObject) } 

我认为Swift没有像ObjC那样强大的reflection,但是有什么解决方法吗?

更新事实certificate,我的代码工作,但我已经简化了演示的目的。 奇怪的部分是,当我将myVar的types更改为某个自定义类的实例时,respondsToSelector停止工作,比方说ClassB。 感觉有点神奇… 🙂

UPDATE2最后我发现了这个问题。 我没有写完整的代码,认为这个问题是在其他地方,无论如何,这里是完整的代码。 MyClassvariables实际上是另一种实现AnotherClassProtocol的AnotherClasstypes

 protocol AnotherClassProtocol { //… } class AnotherClass: AnotherClassProtocol { //… } class MyClass: NSObject { var myVar : AnotherClass! // ... } 

这是造成myClass.respondsToSelector(select器(“setMyVar:”))总是返回false。 原来问题是因为我省略了我的AnotherClass声明中的NSObject的扩展。 它修复之后开始按预期工作:

 class AnotherClass: NSObject, AnotherClassProtocol { //… } 

我仍然在学习Swift,并认为NSObject是不需要的,因为编译器没有抱怨,一切都从NSObject延伸(至less在ObjC)。 那么,我很高兴我发现这个讨厌的bug。

 import Foundation class MyClass: NSObject { var myVar1 : AnyObject! // ... } let myClass: MyClass = MyClass() let hasClassMemberMyVar1 = myClass.respondsToSelector(Selector("setMyVar1:")) // true let hasClassMemberMyVar2 = myClass.respondsToSelector(Selector("setMyVar2:")) // false 

这个对我有用 …

更新,基于OP笔记

 import Foundation class C:NSObject {} class MyClass: NSObject { var myVar1 : C? // Objective-C representable var i: Int = 0 // Objective-C representable var j: Int? = 10 } let myClass: MyClass = MyClass() let hasClassMemberMyVar1 = myClass.respondsToSelector(Selector("setMyVar1:")) // true let hasClassMemberMyVar2 = myClass.respondsToSelector(Selector("setMyVar2:")) // false let hasClassMemberI = myClass.respondsToSelector(Selector("setI:")) // true let hasClassMemberJ = myClass.respondsToSelector(Selector("setJ:")) // false, because Optional<Int> is not representable in Objective-C !!! print(myClass.i.dynamicType, myClass.j.dynamicType) // Int Optional<Int> 

仅具有类types属性

 import Foundation class C:NSObject {} class C1 {} class MyClass: NSObject { var c : C? var cO1: C = C() var cO2: C! var c1: C1 = C1() var c2: C1? var c3: C1! } let myClass: MyClass = MyClass() let hasClassMemberC = myClass.respondsToSelector(Selector("setC:")) // true let hasClassMemberCO1 = myClass.respondsToSelector(Selector("setCO1:")) // true let hasClassMemberCO2 = myClass.respondsToSelector(Selector("setCO2:")) // true let hasClassMemberC1 = myClass.respondsToSelector(Selector("setC1:")) // false, class C1 is not Objective-C representable ... let hasClassMemberC2 = myClass.respondsToSelector(Selector("setC2:")) // false, Optional<C1> is not Objective-C representable ... let hasClassMemberC3 = myClass.respondsToSelector(Selector("setC3:")) // false, ImplicitlyUnwrappedOptional<C1> is not Objective-C representable ... 

比检查select器稍微好一些的方法是使用协议。

 protocol MyClassProtocol { var myVar : AnyObject! {get set} } class MyClass: NSObject, MyClassProtocol { var myVar : AnyObject! // ... } ... let c = MyClass() if let conformingMyClass = c as? MyClassProtocol { // returns true print("yay") conformingMyClass.myVar = "Context" } else { print("nay") } 

这样,就可以更清楚地知道哪些类没有你的属性,而且你也不必使用select器(更多的Swift-y)。

 class MyClass: NSObject { var myVar : AnyObject! // ... } let myClass = MyClass() myClass.respondsToSelector("myVar") // returns true myClass.respondsToSelector("myVar:") // returns false 

Swift 3版本的Ryan Huubert的回答是:

 class MyClass: NSObject { var myVar : AnyObject! // ... } let myClass = MyClass() myClass.responds(to: Selector("myVar")) // returns true myClass.responds(to: Selector("myVar:")) // returns false