views:

340

answers:

4

I want to get the type of NSNumber instance.

I found out on http://www.cocoadev.com/index.pl?NSNumber this:

 NSNumber *myNum = [[NSNumber alloc] initWithBool:TRUE];

 if ([[myNum className] isEqualToString:@"NSCFNumber"]) {
  // process NSNumber as integer
 } else if  ([[myNum className] isEqualToString:@"NSCFBoolean"]) {
  // process NSNumber as boolean
 }

Ok, but this doesn't work, the [myNum className] isn't recognized by the compiler. I'm compiling for iPhone.

+1  A: 
NSString *classString = NSStringFromClass([myNum class]);

That should ger the string you want.

Squeegy
isn't there a way to get the type of the NSNumber without comparing with strings?I know that there is the "objCType" method, but each time I retrieve it, it returns a different value.
okami
+4  A: 

I recommend using the -[NSNumber objCType] method.

It allows you to do:

NSNumber * n = [NSNumber numberWithBool:YES];
if (strcmp([n objCType], @encode(BOOL)) == 0) {
    NSLog(@"this is a bool");
} else if (strcmp([n objCType], @encode(int)) == 0) {
    NSLog(@"this is an int");
}

For more information on type encodings, check out the Objective-C Runtime Reference.

Dave DeLong
A: 

The reason the compiler warns you and it doesn't work is because -[NSObject className] is declared in a category on NSObject on Mac OS X (in NSScriptClassDescription.h) and not declared on iPhone. (It doesn't support AppleScript, obviously.) NSStringFromClass([myNum class]) is what you should use to be safe across all platforms. Odds are that -className is declared as a simple wrapper around NSStringFromClass() anyway...

Quinn Taylor
A: 

NSNumber explicitly doesn't guarantee that the returned type will match the method used to create it, so doing this at all is probably a bad idea.

However, you could probably do something like this (you could also compare to objc_getClass("NSCFNumber") etc., but this is arguably more portable):

Class boolClass = [[NSNumber numberWithBool:YES] class];
/* ... */
if([myNum isKindOfClass:boolClass]) {
  /* ... */
}