respondsToSelector 到 id 类型对象

respondsToSelector to an id type object

在我的 class 中有一个方法可以说是 -aMethod:,它接受一个 id 类型的参数并对该对象进行一些操作。现在我想调用一个方法让该对象的 -someMethod 。但问题是对象类型是 id 并且我无法转换它,因为我不知道哪种类型的对象会出现在这里。在我的代码下方,但它显示错误 no know instant method for the selector someMethod。任何机构都可以帮助处理这种情况。

我不想使用块或委托。

- (void)aMethod:(id)anObject
{
    // other stuff
    if([anObject respondsToSelector:@selector(someMethod)]) [anObject someMethod];
}

如果您不知道将发送给您的确切 class 类型,您应该创建一个协议并拥有所有可能发送的 classes(并实现目标方法)确认该协议。现在您可以转换为(或设置传递给的参数)id < MyProtocol >,编译器会很高兴。

创建 NSObject 的子class,这是您要求的一种类型。在你的情况下 AnObject

现在在此 class 中实施 someMethod,然后使用此 class 作为参数而不是 id

以便您可以按预期调用和实现someMethod

您只需以任何方式向编译器显示该方法。您无需以这种方式键入接收器。 (但我会那样做。)就我个人而言,我更喜欢有一个收集方法的协议。

@protocol MyDelegateProtocol
- (void)someMethod;
@end

// You do not have to use that protocol for typing.
// So you can use your code as you did.

另一种方法是将类别添加到 class。

@interface AnyClassIncludingNSObject( MyDelegateAddition )
- (void)someMethod;
@end

不要实施该类别。

第三种解决方案是将方法添加到 class 发送消息。

- (void)someMethod {}

它总是一样的:编译器必须看一遍。

除了这里的其他答案:

如果出于某种原因你不想声明一个协议,你可以这样做:

if ([anObject respondsToSelector:@selector(someMethod)]) {
    [anObject performSelector:@selector(someMethod)];
}

如果需要传参还有performSelector:withObject:performSelectorOnMainThread

据我了解,您不想按照其他人建议的正确方式执行此操作。所以,为了解决这个问题,我会先删除警告:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"

... your code here ...

#pragma clang diagnostic pop

只需在 #pragma 秒之间移动您的代码。

其次,我会 #import 声明了 someMethod 的 class,然后在调用时将 'unknown' 对象转换为 class方法。 喜欢:[(MySuperClassThatHasSomeMethodDeclared *)anObject someMethod];

是的,别担心,您的 someMethod 将在您传递的对象上被调用。

那么,这是您解决问题的肮脏方法。祝你好运!