3

Why are the Objective-C runtime methods object_getInstanceVariable and object_setInstanceVariable are not available under Automatic Reference Counting and what can I do about it?

object_getInstanceVariable is buggy when the instance variable's size is larger than the development target's pointer size. How can I get around this?

Ethan Reesor
  • 2,090
  • 1
  • 23
  • 40

2 Answers2

4

Use the valueForKey: and setValue:forKey: methods instead. These allow you to read/write any instance variable of an object. For primitive-typed instance variables these methods return/take values wrapped as NSNumber or NSValue objects.

You have instance variables larger than the pointer size, maybe struct's? Here are some code fragments showing use with a struct, first let's define a struct:

typedef struct
{
   int i;
   float f;
   char c;
} ThreePrimitives;

and a class with a (private) instance variable:

@interface StructClass : NSObject
...
@end

@implementation StructClass
{
   ThreePrimitives myStruct;
}
...
@end

To set the instance variable:

ThreePrimitives a = { 42, 3.14, 'x' };
NSValue *wrapA = [NSValue value:&a withObjCType:@encode(ThreePrimitives)];
[sc setValue:wrapA forKey:@"myStruct"];

To read the instance variable:

ThreePrimitives b;
NSValue *extracted = [sc valueForKey:@"myStruct"];   
[extracted getValue:&b];

HTH

CRD
  • 52,522
  • 5
  • 70
  • 86
  • 1
    @FireLizzard - Instance variables are not `readonly`, do you mean a property or a `const`? The above methods work fine to access the backing variable of a property, regardless of whether the property is declared `readonly` or `readwrite`. – CRD Jan 22 '14 at 09:38
3

The two runtime functions work (under ARC) for instance variables that are pointer types. When those instance variables happen to be objects, the implementation of these functions is such that it is not compatible with ARC. That means ARC wouldn't be able to properly do it's job if you used them and it simultaneously. Thus, they are disabled.

To access an instance variable of any type, use ivar_getOffset. To access an object instance variable, use object_getIvar. To find an Ivar structure, use class_copyIvarList to get the list and ivar_getName to find the one you want.

DISCLAIMER: I got the answer from this thread.

Ethan Reesor
  • 2,090
  • 1
  • 23
  • 40