What is the difference between *(id *)((char *)object + ivar_getOffset(ivar)) and object_getIvar(object, ivar)

StackOverflow https://stackoverflow.com/questions/3572068

  •  01-10-2019
  •  | 
  •  

Question

According the Objective-C runtime reference:

ivar_getOffset Returns the offset of an instance variable.

ptrdiff_t ivar_getOffset(Ivar ivar) Discussion For instance variables of type id or other object types, call object_getIvar and object_setIvar instead of using this offset to access the instance variable data directly.

Declared In runtime.h

Why is this? What does object_getIvar do to object types?

EDIT: changed question from subscripting (void *) to (id *).

Was it helpful?

Solution

There is no difference between those two approaches when it comes to getting the value of the ivar. You can verify this by looking at object_getIvar()'s implementation in Apple's open-source Obj-C runtime code.

object_setIvar() does more than just assign to an offset from the object pointer. It is careful to call through to the garbage-collection runtime function objc_assign_ivar() to perform the actual assignment.

More magic might be added to either of these functions in future; in general, you should use the highest-level API available at any given time.

OTHER TIPS

Perhaps it's not that object_getIvar does something different, but that instance variables of type id or other object types are commonplace, and that calling ivar_getOffset and appending the result to the value of object and then casting to the appropriate type is much more cumbersome.

Note that you cannot reliably increment the value of a void *, based on the following information from the C99 standard (emphasis mine):

C99 §6.2.5 (1): (...) Types are partitioned into object types (types that fully describe objects), function types (types that describe functions), and incomplete types (types that describe objects but lack information needed to determine their sizes).

C99 §6.2.5 (19): The void type comprises an empty set of values; it is an incomplete type that cannot be completed.

C99 §6.5.6 (2): For addition, either both operands shall have arithmetic type, or one operand shall be a pointer to an object type and the other shall have integer type. (Incrementing is equivalent to adding 1.)

C99 §6.5.2.1 (1): One of the expressions shall have type “pointer to object type”, the other expression shall have integer type, and the result has type “type”.

To increment a pointer by an arbitrary number, you can use char * instead.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top