6

In Objective-C, is id exactly the same as void * in C? (a generic pointer type).

If so, when we use

id obj = [[Fraction alloc] init];
[obj methodName];
obj = [[ComplexNumber alloc] init];
[obj anotherMethodName];

When the method is called, by what way does the program know what class obj is?

Cœur
  • 37,241
  • 25
  • 195
  • 267
nonopolarity
  • 146,324
  • 131
  • 460
  • 740
  • I think this gets resolved at runtime if I'm not mistaken, caller is loaded into a register (eax I think) and then function is loaded into ecx and then obj-c does some checking to send a "message" to that object which is the method call (this can fail silently I believe) IIRC. It's been a while since I messed with/looked at obj-c internals so I may be wrong on some points. For all intents and purposes you can look at it as void * but with less restrictions in some cases – Jesus Ramos Apr 23 '12 at 01:35
  • possible duplicate of [objective c difference between id and void *](http://stackoverflow.com/questions/1304176/objective-c-difference-between-id-and-void) – jscs Apr 23 '12 at 03:04

3 Answers3

5

id is not the same as a void *. id is a pointer to an Objective C object of unknown type; like the object datatype of C# or Java. A void* can point at anything; a non-nil id is expected to point at a data structure that's common to all ObjC objects and contains a pointer to their respective class data.

The ObjC runtime - the implementation of alloc/init/etc. - makes sure all the valid objects have the right class pointer in them.

IIRC, in Apple's implementation the pointer-sized variable that id points at is, in fact, the pointer to the class.

In the class' data block, there's a list of methods that maps method signature to the function pointer to the method implementation. From there, it's a fairly simple lookup that happens in run time when you send a message to (i. e. call a method in) an object. Also a pointer to the base class so that the method lookup may continue up the inheritance tree.

That, by the way, is why derefencing a void pointer is a compiler error while sending messages to an id is legal, if statically unsafe.

Seva Alekseyev
  • 59,826
  • 25
  • 160
  • 281
  • 1
    Its not quite the same object in C# and Java, NSObject is the same. id is a way to tell the compiler I am going to use dynamic typing with this object, id is equivalent to var in JavaScript. – Nathan Day May 02 '12 at 23:39
5

id in Objective-C is not eactly the same as void * in C.

From Apple's "The Objective-C Programming Language":

typedef struct objc_object {
   Class isa;
} *id;

Which means, id is a pointer to an objc_object structure, which is different from a pointer to void.

Every object thus has an isa variable that tells it of what class it is an instance. Since the Class type is itself declared as a pointer.

typedef struct objc_class *Class;

And regarding, how the program tell the class during method invocation?, here is this from the same programming guide cited above:

The isa instance variable identifies the object's class -what kind of object it is. Objects with the same behavior (methods) and the same kinds of data (instance variables) are members of the same class.

Objects are thus dynamically typed at runtime. Whenever it needs to, the runtime system can find the exact class that an object belongs to, just by asking the object. (To learn more about the runtime, see Objective-C Runtime Programming Guide.)

According to the guide, id, nil, and other basic types of Objective-C are defined in the header file objc/objc.h.

Only You
  • 2,051
  • 1
  • 21
  • 34
1

Yes, id is just a generic pointer. Class resolution at compile-time is just to inform the user of warnings and errors. However, a veritable with a type of id will not be tied to any particular class at compile time. The actual class will not be known until the object is accessed at runtime. If the object is a subclass of NSObject, which it most likely will be, your code can asks the object what it's class is.

[myObject class] will return the class of myObject. [myObject isMemberOfClass:[SomeClass class]] will return a BOOL indicating whiter ir not myObject is a member of the class SomeClass.

If your code calls a method on myObject, the runtime will attempt to make the call, even if the object does not respond to that method. If myObject does not implement that method, a runtime exception will occur.

You can also ask myObject ahead of time to find out if the method is valid with [myObject respondsToSelector:@selector(myCoolMethod)].

Jeff Wolski
  • 6,332
  • 6
  • 37
  • 69