Is it possible to get a struct property by its string name in Objective-C?
I have an object that has a property that looks like this:
struct someStruct{
float32 x, y;
};
And what I would like to do is call the getter on this struct property via the line:
id returnValue = [theObject performSelector:NSSelectorFromString(@"thePropertyName")];
But as you can see, "performSelector:" returns an object, not a structure. I've tried every casting method I could think of, but to no avail, which makes me think I'm missing something - maybe something simple ...
Any ideas on how returnValue can be coaxed back into a struct? Thank!
Edit: Whoever the original responder was (he has since deleted his post for some reason) - you were right: the following, based on your answer, works:
StructType s = ((StructType(*)(id, SEL, NSString*))objc_msgSend_stret)(theObject, NSSelectorFromString(@"thePropertyName"), nil);
Edit 2: A fairly detailed look at the problem can be found here .
Edit 3: For symmetry, here's how to set a struct property by its string name (note that this is exactly how the accepted answer does the setting, whereas my problem required a slightly different approach for the getter mentioned in the first board above):
NSValue* thisVal = [NSValue valueWithBytes: &thisStruct objCType: @encode(struct StructType)];
[theObject setValue:thisVal forKey:@"thePropertyName"];
source to share
You can do this using key value encoding by wrapping it struct
inside NSValue
(and expanding it when it is returned). Consider a simple class with a struct property as shown below:
typedef struct {
int x, y;
} TwoInts;
@interface MyClass : NSObject
@property (nonatomic) TwoInts twoInts;
@end
We can then wrap and deploy struct
in an instance NSValue
to pass it to and from KVC methods. Below is an example of setting a structure value using KVC:
TwoInts twoInts;
twoInts.x = 1;
twoInts.y = 2;
NSValue *twoIntsValue = [NSValue valueWithBytes:&twoInts objCType:@encode(TwoInts)];
MyClass *myObject = [MyClass new];
[myObject setValue:twoIntsValue forKey:@"twoInts"];
To get a structure as a return value, use the method NSValue
getValue:
:
TwoInts returned;
NSValue *returnedValue = [myObject valueForKey:@"twoInts"];
[returnedValue getValue:&returned];
source to share