在我的班级中有一个方法,比如-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];
}
答案 0 :(得分:7)
您只需以任何方式向编译器显示该方法。你不需要那样输入接收器。 (但我会这样做。)我个人更喜欢有一个收集方法的协议。
@protocol MyDelegateProtocol
- (void)someMethod;
@end
// You do not have to use that protocol for typing.
// So you can use your code as you did.
另一种方法是向类添加类别。
@interface AnyClassIncludingNSObject( MyDelegateAddition )
- (void)someMethod;
@end
不实施该类别。
第三种解决方案是将方法添加到发送消息的类中。
- (void)someMethod {}
总是一样的:编译器必须一次看到它。
答案 1 :(得分:2)
如果您不知道将要发送的确切类类型,则应创建协议并使所有可能发送的类(以及实现目标方法的类)确认该协议。现在你可以强制转换(或设置传递给id < MyProtocol >
的参数,编译器会很高兴。
答案 2 :(得分:1)
据我了解,你不想像其他人建议的那样以正确的方式做到这一点。所以,为了解决这个问题,我首先会删除警告:
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
... your code here ...
#pragma clang diagnostic pop
只需在#pragma
s。
其次,我会#import
宣布someMethod
的班级,然后投出“未知”字样。调用方法时对该类的对象。
喜欢:[(MySuperClassThatHasSomeMethodDeclared *)anObject someMethod];
而且,是的,不用担心,你的someMethod
将被调用你已经过去的对象。
所以,这是你解决问题的DIRTY方式。祝你好运!
答案 3 :(得分:0)
创建NSObject
的子类,这是您的要求类型。在您的情况下AnObject
。
现在在此类中实现someMethod
,然后将此类用作参数而不是id
。
这样您就可以按预期调用和实施someMethod
。
答案 4 :(得分:0)
除了其他答案:
如果由于某种原因你不想申报协议,你可以这样做:
if ([anObject respondsToSelector:@selector(someMethod)]) {
[anObject performSelector:@selector(someMethod)];
}
如果您需要传递参数performSelector:withObject:
和其他人,还有performSelectorOnMainThread
。