Can I get the type of a class member variable

I have defined a class as

@interface myClass:NSObject{
NSNumber *member1;
NSData *data1;
}

@end

I want to know if it is possible to get the type of member1 from a NSString variable @"member1".

for example:
NSString *str1=@"member1";
I want to know that the member1 in myClass is really a NSNumber type.

thanks

iOS 4

Posted on Sep 6, 2010 3:23 AM

Reply
5 replies

Sep 6, 2010 4:28 AM in response to sinokai

Hi Sinokai, and welcome to the Dev Forums!

Take a look at [isMemberOfClass:|http://developer.apple.com/iphone/library/documentation/Cocoa /Reference/Foundation/Protocols/NSObject Protocol/Reference/NSObject.html#//appleref/doc/uid/20000052-BBCEBEIC] and [isKindOfClass:|http://developer.apple.com/iphone/library/documentation/Cocoa/R eference/Foundation/Protocols/NSObject Protocol/Reference/NSObject.html#//appleref/doc/uid/20000052-BBCBFBDJ] in the +NSObject Protocol Reference+. However, if your purpose is to make sure an object will respond to a particular method message, the best test is [respondsToSelector:|http://developer.apple.com/iphone/library/documentation/Co coa/Reference/Foundation/Protocols/NSObject Protocol/Reference/NSObject.html#//appleref/doc/uid/20000052-BBCEHCCE]. For example, as discussed in the doc, it's not a good idea to use isKindOfClass: to determine if an array object is mutable. Sending respondsToSelector:@selector(insertObject:atIndex:), would be the best way to make that decision.

\- Ray

Sep 6, 2010 6:20 PM in response to RayNewbie

Dear Ray
I am so thankful for your reply, especially to my first question in the Dev Forums.

I have known the "member1" is a member of myClass. However, I want to know the Return Type of member variable automatically from the NSString @"member1".

I have tried the following method but fail to get the right result.

NSMethodSignature *signature = [[myClass class] instanceMethodSignatureForSelector: NSSelectorFromString(@"member1"];
if (strcmp([signature methodReturnType],@endcode(NSData *))==0){
NSLog(@"It is a NSData Type");
}else{
NSLog(@"Non-NSData Type");
}

By the above method,
I got a result of "It is a NSData Type" . But it is really a "Non-NSData Type".

(*The setter and getter of member1 have already been defined)

Is there any other function to get the Return type of member variable?

Sep 6, 2010 8:45 PM in response to sinokai


NSMethodSignature *signature = [[myClass class] instanceMethodSignatureForSelector: NSSelectorFromString(@"member1"];
if (strcmp([signature methodReturnType],@endcode(NSData *))==0) {
NSLog(@"It is a NSData Type");
}else{
NSLog(@"Non-NSData Type");
}


1. Use the { code } tags to format code. Just reply and quote this response to see how to use them.

2. For all you know, it could be a problem in your strcmp(). What happens when you put the following line just before your if ?

NSLog(@"%s", [signature methodReturnType]);

Sep 7, 2010 3:00 AM in response to sinokai

Ok Sinokai, I might understand your requirement now. I don't think there's any way to get the type info you want from the getter signature at runtime. At that stage all object pointers are considered to be type id. The type of a pointer's target is no longer of interest and isn't included in the runtime signature. E.g., as you observed, @encode(NSData*) produces the same string ("@") as @encode(NSArray*). Similarly, [signature methodReturnType] returns the same string for any object pointer. The object type info included in a pointer's declaration is only used by the compiler to generate type mismatch warnings.

I think the correct approach is to use the low-level obj-c runtime functions as shown in this SO thread: [How to use @encode() to get @“NSArray” in Objective-C|http://stackoverflow.com/questions/784992/how-to-use-encode-to-get- nsarray-in-objective-c]. As you can see, the OP had his code working, but was concerned that the string literal he was using would fail sooner or later because the result of @encode isn't guaranteed to be the same on all platforms. But when he used @encode(NSArray) that didn't work at all (actually @encode(NSArray*) appears in the post, but I'm guessing that was just a typo--on my system the string produced by @encode() couldn't be found in the property attributes string regardless of whether I encoded the object or the object pointer).

This outcome seems to contradict the doc (see [Property Type String|http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual /ObjCRuntimeGuide/Articles/ocrtPropertyIntrospection.html#//apple_ref/doc/uid/TP 40008048-CH101-SW6] in the Objective-C Runtime Programming Guide):
You can use the property_getAttributes function to discover the name, the @encode type string of a property, and other attributes of the property.
The string starts with a T followed by the @encode type and a comma, and finishes with a V followed by the name of the backing instance variable...

Given the difference between the doc and what I'm seeing on iOS 3.12 (I haven't looked at the strings on my Mac yet), I think it would be much safer to search for the unencoded class name in the property attributes string. This example makes that change to the SO code:

- (BOOL)valueForKeyIsData:(NSString*)key fromTarget:(Class)target {
// NSString *lowerCaseKey = [self convertToKVCKey:key];
objcpropertyt property = class_getProperty(target, [key UTF8String]);
NSString *propertyAttrs = [NSString stringWithUTF8String:property_getAttributes(property)];
NSString *encodedType = @"NSData"; // <-- instead of a quoted literal or @encode(NSData)
NSLog(@"%s: propertyAttrs=%@ encodedType=%@", _func_, propertyAttrs, encodedType);
NSRange range = [propertyAttrs rangeOfString:encodedType options:NSLiteralSearch];
return range.location != NSNotFound;
}

I couldn't find any function like [property getName|http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/ ObjCRuntimeRef/Reference/reference.html#//apple_ref/c/func/propertygetName] to extract the unencoded class name from the attributes string. But you might also want to check out [ivar getTypeEncoding|http://developer.apple.com/iphone/library/documentation/Cocoa/Re ference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/c/func/ivargetTypeEncoding] and [method getTypeEncoding|http://developer.apple.com/iphone/library/documentation/Cocoa/Re ference/ObjCRuntimeRef/Reference/reference.html#//apple_ref/c/func/methodgetTypeEncoding].

- Ray

This thread has been closed by the system or the community team. You may vote for any posts you find helpful, or search the Community for additional answers.

Can I get the type of a class member variable

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple Account.