athira
athira

Reputation: 31

How to call methods on an object of type id

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

Answers (3)

uliwitness
uliwitness

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:

You are calling a method that has not been declared

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.

You are calling a class method on an instance (object) or an instance method on a class

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.

You are calling a method that the given object/class does not have

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.

How does 'id' figure into this?

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

Partho Biswas
Partho Biswas

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

tanz
tanz

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

Related Questions