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"];

      

+3


source to share


1 answer


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];

      

+4


source







All Articles