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

标签 ios swift reflection

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

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

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

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)。

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)。

关于ios - 如何检查对象是否具有存储属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35398909/

相关文章:

ios - 在 View Debugger 中查看时如何找到连接到任何 UIView 的相应 socket ?

c# - 在结构上调用内部方法

ios - 从 WebView 中的链接打开 Mobile Safari

ios - 使用文本字段时,我试图让键盘在 IOS 中消失

ios - 自动布局停止 UITapGestureRecognizer?

ios - AFNetworking - 对 REST 进行 HTTP POST,发送带有 Base64 字符串图像的 JSON

swift - SpriteKit 使图像适合屏幕,而不是拉伸(stretch)过去

ios - EXC_BAD_ACCESS w/OpenCV `cv::aruco::detectMarkers()` 在 IOS 上

java - 如何通过 Byte Buddy 为类中的公共(public)方法定义新注释

java - 根据调用方法更改返回类型