Reputation: 31
when I'm trying to call a method on an object of type id, i get a warning raised (method not found). how i call the method :
Class A *instanceACasted = (ClassA *)idvalue ;
then call the method
[instanceACasted methodCall];
This is one way but i dont know about the class name using id how i call the method
Upvotes: 0
Views: 1012
Reputation: 8793
The correct answer depends heavily on what you are actually doing. Your code doesn't compile, and your error message "method not found" does not exist in Clang, so I can't tell what is actually happening. Also, your subject contradicts what I might guess from your code (there is no mention of "id" in your code). Here are a few guesses:
ObjC mostly reads code from top to bottom, and reads each source file (implementation file, .m file, not header) separately, as its own "compilation unit". So if your source file tries to call a method that is not in your file, you'll get an error message like error: no known instance method for selector 'doSomething'
or error: no known class method for selector 'doSomething'
.
To fix that, you need to #import
the header that declares the class/protocol that defines the method you want to call.
Class methods start with a +, instance methods with a -. They are totally separate. So if you declare a method with a +, then call it on an object of that type (instead of on myObject.class or the class name), the compiler may warn you about error: no known instance method for selector 'doSomething'
resp. error: no known class method for selector 'doSomething'
. Here the important part is that it is looking for a class method, even though an instance method exists, and vice versa.
In that case, you get an exception that bounces you back into the run loop and a log message at runtime. This could mean that your code is expecting a newer OS's version of a class (which has that method) but is running on an older OS (where this method didn't exist yet). In that case, you get a message like unrecognized selector sent to instance 0x7fffdb13cf38
or unrecognized selector sent to class 0x7fffdb13cf38
.
To fix that, you can check whether an object responds to a given method by asking it [theObject respondsToSelector: @selector(doSomething)]
, and only then calling it, otherwise doing something equivalent that doesn't rely on that method. Or you could check if that method is available ahead of time and just hide the button or whatever that needs this on older OSes that way.
Note that, if you had e.g. an NSObject*
and you knew that in one special case it could actually be an NSString*
, and you use -respondsToSelector:
to verify that it implements @selector(characterAtIndex:)
in that case, you may still get an error message that NSObject
instances do not responds to -characterAtIndex:
. In this case, you can turn off that warning by doing:
NSObject* myNSObject = myArray.firstObject;
if( [myNSObject respondsToSelector: @selector(characterAtIndex:)] )
[(NSString*)myNSObject characterAtIndex: 0];
or whatever. You usually never write code like this, though. Checking "what class is my object" is usually an indicator that you built your class hierarchy wrongly, so I only mention that for completeness' sake.
You mention id
in your headline, but your example doesn't use it. If you call a method on id
, ObjC will let you do anything. All it wants is that somewhere there is a class or instance method declaration for the given method, on any object. In that case, it will only blow up at runtime if you call a method the given object doesn't have.
Upvotes: 0
Reputation: 2330
To get rid of the warning method not found
, you must cast/convert your id
type object to the proper object type. But in this case you need to know the Class
name of id
type object.
If you don't know the class name then follow this answer.
Upvotes: 0
Reputation: 2547
You can use introspection and performSelector
:
SEL selector = @selector(yourMethodSignature:);
if ([obj respondsToSelector:selector]) {
[obj performSelector:selector];
}
Apple documentation on how to use introspection.
Upvotes: 1