tags:

views:

161

answers:

2

Given a variable id x and a string NSString *s how can I get the instance attribute with name s for variable x?

ie. If we write NSString *s=@"a", then we want x.a

+2  A: 

The Objective-C Runtime Reference lists

Ivar class_getInstanceVariable(Class cls, const char * name)

which returns an opaque type representing an instance variable in a class. You then pass that to

id object_getIvar(id object, Ivar ivar)

to get the actual instance variable. So you could say

#import <objc/runtime.h>

id getInstanceVariable(id x, NSString * s)
{
    Ivar ivar = class_getInstanceVariable([x class], [s UTF8String]);
    return object_getIvar(x, ivar);
}

if the instance variable is an object. However, if the instance variable is not an object, call

Ivar object_getInstanceVariable(id obj, const char * name, void ** outValue)

passing in a pointer to a variable of the right type. For example, if the instance variable is an int,

int num;
object_getInstanceVariable(x, [s UTF8String], (void**)&num);

will set num to the value of the integer instance variable.

Jon Reid
Actually, object_getIvar takes an Ivar for the second argument.
Casebash
Use Ivar class_getInstanceVariable(Class cls, const char* name) to get the Ivar to pass in
Casebash
Quite right! +1 Casebash
Jon Reid
+1  A: 

Providing that x is key-value coding compliant for the a property, you can just do this:

id result = [x valueForKey:s]
Rob Keniger
Worth remembering
Casebash