respondsToSelector 在选择器中具有不同的参数类型

Posted

技术标签:

【中文标题】respondsToSelector 在选择器中具有不同的参数类型【英文标题】:respondsToSelector with different argument types in selector 【发布时间】:2013-02-12 10:08:21 【问题描述】:

假设我们有不同的对象,它们具有相同的方法名称但具有不同的参数类型,例如:getMethod:(NSNumber*)aNumbergetMethod:(NSString*)aString

如何通过respondsToSelector或其他方式检查对象是否响应具有特定参数类型的选择器,如下所示:

[myObjectA respondsToSelector:@selector(getMethod:(NSNumber*))]

你是怎么做到的? 谢谢。

【问题讨论】:

你不能声明两个具有相同名称和不同参数类型的方法。 好的,假设我们有不同类型的对象,具有相同的方法名称,但具有不同的参数类型。那你怎么办? 你必须直接使用Objective-C Runtime Functions 你还是做不到。您需要有一个以id 作为参数的一个 方法,然后确定它在该方法中的对象类型。 @borrden 不,他可以自己写responsToSelector。 【参考方案1】:

您有几种方法可以找到选择器参数的类型名称。 例如,此代码将起作用:

Method method = class_getInstanceMethod([self class], @selector(someMethod:param2:param3:));
char type[256];
int argsNumber = method_getNumberOfArguments(method);
for (int i = 0; i < argsNumber; i++) 
    method_getArgumentType(method, i, type, 256);
    NSLog(@"%s", type);

第一个和第二个日志参数是系统参数,你对它们不感兴趣,所以你需要另一个树线。

下面的代码也会给你同样的结果

NSMethodSignature *sig = [self methodSignatureForSelector:@selector(someMethod:param2:param3:)];
int args = [sig numberOfArguments];
for (int i = 0; i < args; i++) 
    NSLog(@"%s", [sig getArgumentTypeAtIndex:i]);

someMethod:param2:param3: 例如可以有这样的实现

- (BOOL) someMethod:(NSString *)str param2:(UIView *)view param3:(NSInteger)number

    return NO;

但是!当然,我们有很大但在这里))在这两种情况下,您都将拥有带有 const char * 字符串的参数类型名称,长度为一个符号。编译器对类型名称进行编码,如here 所述。您可以将 int 与 char 不同,但不能将 UIView 与 NSString 不同。对于所有 id 类型,您将拥有类型名称“@”,这意味着它是 id。悲伤但真实。不幸的是,我还没有找到任何方法来获得完整的类型名称或给出解码。如果你会找到这种方式,请告诉我。

所以这是解决方案。希望您能找到在您的项目中使用这种方法的方法。

【讨论】:

谢谢罗斯特!即使您的回答没有直接回答我的问题,它也解释了一种使用 Runtime 的有趣方式。 希望 Apple 大佬在 SDK 的功能版本中发布满足我需求的方法。 他们是否会这样做是值得怀疑的,因为您的需求违背了他们冗长命名的理念。我的建议是简单地重构,以便它们的名称能够真正表明它们在做什么。哪怕是getMethodFromNumber:或者getMethodFromString:这样简单【参考方案2】:

您实际上无法区分方法参数类型,但也许您可以这样做:

if([myObject isKindOfClass:[A class]])
     [myObjectA getMethod:aNumber];
else if([myObject isKindOfClass:[B class]])
     [myObjectA getMethod:aString];

您不需要检查它是否响应选择器,因为您已经检查了它的类型是否正确。也许您的问题比这更复杂,但如果不是,这应该可以工作。

【讨论】:

以上是关于respondsToSelector 在选择器中具有不同的参数类型的主要内容,如果未能解决你的问题,请参考以下文章

_delegate respondsToSelector:selector 没有调用方法

无法在 Mac 上使用 ARC 使用 respondsToSelector

respondsToSelector的使用

如何在 Swift 4 中使用 respondsToSelector 验证来自 HomeKit 的值的方法字节

respondsToSelector 发送到释放的对象

respondsToSelector和 instancesRespondToSelector的理解