如何在id类型的对象上调用方法

时间:2017-03-24 09:01:16

标签: ios objective-c

当我尝试在id类型的对象上调用方法时,我收到警告(找不到方法)。我怎么称呼这个方法:

Class A *instanceACasted = (ClassA *)idvalue ;

然后调用方法

[instanceACasted methodCall];

这是一种方式,但我不知道使用id的类名称如何调用方法

3 个答案:

答案 0 :(得分:1)

您可以使用内省和performSelector

SEL selector = @selector(yourMethodSignature:);
if ([obj respondsToSelector:selector]) {
    [obj performSelector:selector];
}

关于how to use introspection的Apple文档。

答案 1 :(得分:0)

要消除警告method not found,您必须将id类型对象转换/转换为正确的对象类型。但在这种情况下,您需要知道Class类型对象的id名称。

如果您不知道班级名称,请遵循此answer

答案 2 :(得分:0)

正确的答案在很大程度上取决于你实际在做什么。您的代码没有编译,并且找不到您的错误消息"方法"在Clang中不存在,所以我不知道实际发生了什么。此外,您的主题与我可能从您的代码中猜到的相矛盾(在您的代码中没有提及" id")。以下是一些猜测:

您正在调用尚未声明的方法

ObjC主要从上到下读取代码,并分别读取每个源文件(实现文件,.m文件,而不是标题),作为其自己的编译单元"。因此,如果您的源文件试图调用不在您文件中的方法,则会收到error: no known instance method for selector 'doSomething'error: no known class method for selector 'doSomething'之类的错误消息。

要解决此问题,您需要#import标头,该标头声明定义您要调用的方法的类/协议。

您正在实例(对象)上调用类方法或在类

上调用实例方法

类方法以+开头,实例方法以 - 开头。它们是完全分开的。因此,如果使用+声明一个方法,然后在该类型的对象上调用它(而不是在myObject.class或类名称上),编译器可能会警告您error: no known instance method for selector 'doSomething' resp。 error: no known class method for selector 'doSomething'。这里重要的部分是它正在寻找一个类方法,即使存在实例方法,反之亦然。

您正在调用给定对象/类没有的方法

在这种情况下,您会收到一个异常,它会将您反弹回运行循环并在运行时将发送给日志消息。这可能意味着您的代码期望一个较新的操作系统版本的类(具有该方法)但是在较旧的操作系统上运行(此方法尚未存在)。在这种情况下,您会收到unrecognized selector sent to instance 0x7fffdb13cf38unrecognized selector sent to class 0x7fffdb13cf38等消息。

要解决这个问题,你可以通过询问一个对象[theObject respondsToSelector: @selector(doSomething)]来检查一个对象是否响应给定方法,然后再调用它,否则做一些不依赖于该方法的东西。或者您可以提前检查该方法是否可用,只需隐藏按钮或那些在旧操作系统上需要的方法。

请注意,如果您有例如一个NSObject*,你知道在一个特殊情况下它实际上可能是NSString*,你使用-respondsToSelector:来验证它是否实现了@selector(characterAtIndex:),在这种情况下,你仍然可以收到NSObject个实例未响应-characterAtIndex:的错误消息。在这种情况下,您可以通过执行以下操作来关闭该警告:

NSObject* myNSObject = myArray.firstObject;
if( [myNSObject respondsToSelector: @selector(characterAtIndex:)] )
    [(NSString*)myNSObject characterAtIndex: 0];

或其他什么。但是,你通常不会写这样的代码。检查"我的对象是什么类"通常是你错误地构建了你的类层次结构的指示器,所以我只提到它的完整性'缘故。

' id'想到这个吗?

您在标题中提及id,但您的示例并未使用它。如果您在id上调用方法,ObjC将允许您执行任何。它只需要在任何对象上的某个地方有给定方法的类或实例方法声明。在这种情况下,如果你调用给定对象没有的方法,它只会在运行时爆炸。