Cen*_*ion 4 reflection ios swift
我需要检查一个对象的类是否有一个可用于赋值的成员.让我们说有一个课程:
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的类型更改为某个自定义类的实例,respontsToSelector就会停止工作,比方说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中).好吧,我很高兴我发现了这个讨厌的bug.
比检查选择器稍微好一点的方法是使用协议.
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).
Ryan Huubert 的答案的 Swift 3 版本:
class MyClass: NSObject {
    var myVar : AnyObject!
    // ...
}
let myClass = MyClass()
myClass.responds(to: Selector("myVar")) // returns true
myClass.responds(to: Selector("myVar:")) // returns false
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>
仅限类类型属性
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 ...
| 归档时间: | 
 | 
| 查看次数: | 7851 次 | 
| 最近记录: |