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

2024-02-04

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

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 那样强大的反射功能,但是有什么解决方案吗?

UPDATE事实证明我的代码可以工作,但是我出于演示目的对其进行了简化。奇怪的是,一旦我将 myVar 的类型更改为某个自定义类(例如 ClassB)的实例,respondsToSelector 就会停止工作。感觉有点神奇...:)

UPDATE2最后我发现了问题。我还没有写完整的代码,以为问题出在其他地方,无论如何,这是完整的代码。 MyClass 变量实际上是其他实现 AnotherClassProtocol 的 AnotherClass 的类型

protocol AnotherClassProtocol {
  //…
}

class AnotherClass: AnotherClassProtocol {
  //…
}

class MyClass: NSObject {

  var myVar : AnotherClass!
  // ...
}

这导致 myClass.respondsToSelector(Selector("setMyVar:")) 始终返回 false。事实证明,问题是因为我在 AnotherClass 声明中省略了 NSObject 的扩展。在我修复该问题后,它开始按预期工作:

class AnotherClass: NSObject, AnotherClassProtocol {
  //…
}

我仍在学习 Swift,并认为不需要 NSObject,因为编译器没有抱怨,并且一切都从 NSObject 扩展(至少在 ObjC 中)。好吧,我很高兴我发现了这个讨厌的错误。


比检查选择器稍微好一点的方法是使用协议。

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")
}

这样,哪些类拥有和不拥有您的属性就更加明确,并且您不必费力使用选择器(更加 Swift-y)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何检查对象是否具有存储的属性? 的相关文章

随机推荐