何时使用respondsToSelector vs objc_getClass

时间:2014-12-21 09:17:53

标签: ios swift

if respondsToSelector("UIAlertController"){
    //do something
}

if objc_getClass("UIAlertController") != nil{
    //do something
}

这两者总体上具有相同的结果。是否有一个比另一个更好的情况?或者只应该使用其中一个而另一个被遗忘?

3 个答案:

答案 0 :(得分:2)

respondsToSelector :这主要用于检查对象是否引用,可以调用特定方法。例如,object继承自某些基类或由某些协议实现,那么最好检查对象是否能够响应该方法,然后只调用它。

否则会抛出运行时错误,找不到类型的方法。

if([obj respondsToSelector:@selector(anyMethod)]) {
   [obj fizzyWizzle];
}
else {
   // do something
}

objc_getClass :指定类的Class对象,如果未向Objective-C运行时注册该类,则为nil。这意味着,您是否能够访问此课程,如果该课程不存在,那么它将返回' nil'。所以,

if objc_getClass("UIAlertController") != nil{
    // it means, these class is available in SDK, hence its iOS version is 8.x
    // here you can alloc - init and use UIAlertController functionality
}
else {
   // class could not be found
   // iOS version is < 8.0
   // here that class is not available hence use UIAlertView which is supported by iOS 7 and earlier.
}

希望这有帮助。

答案 1 :(得分:1)

要检查班级存在,您必须使用objc_getClass。 (对于与iOS版本的类兼容性)

要检查实现方法或方法的类是否可用,您需要使用respondsToSelector(对于版本的方法可用性)

答案 2 :(得分:1)

这两种方法总体上没有相同的结果。

响应选择器

第一种情况respondsToSelectorNSObject协议的一部分,它将简单地指示一个对象是否能够在调用时响应具有给定签名的消息。它可以用于许多情况:

  • 多态性。即,非正式协议,或者特别是与conformsToProtocol一起用于检查实例(任何类)是否响应@optional指令下的协议部分。
  • 用于决定是否将邮件转发给其他目标。
  • 用于在运行时检测具有附加功能的对象,例如将事务/回滚功能放在持久模型对象上。
  • 在发布/订阅类型方案中。

获取课程

第二种方法是Objective-C运行时的低级成员。它用于简单地检查对象呈现的类的类型。 (它将检查isa指针)。 NSObject协议上有一些方法可以做同样的事情,并且通常建议使用这些方法,除非您有特定的理由退回到较低级别的API。这些方法是[an instance class][anInstance isKindOfClass]

将instanceof替换为Polymorphism

虽然查询对象的类有很多有效的用途,但在典型的应用程序中,它通常是一个设计缺陷。有一种称为“用多态性替换instanceof”的重构模式。我们的意思是,而不是向对象询问它是什么类,然后做一些事情,而不是基于此,而是创建一个协议,让每个可能的类以特定的方式实现该协议的方法。示例:

if ([foo isKindOfClass:[Holiday class]]) {
    //evaluate if approved
} else if ([foo isKindOfClass:[SickLeave class]]) {
    //evaluate if approved
}

相反。 。

id<Leave> leave;
[leave approveOrDecline]