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?
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 theClass
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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With