Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

argument isKindOfClass: [NSNumber class] - sane way to check this?

So I was playing with something where the class type of the arg is unknown until runtime. like this:

- (NSNumber *)doWhatever:(id)arg
{
    // this ALWAYS FAILS
    if ([arg isKindOfClass:[NSNumber class]]) {
        return arg;
    }
    else {
        // what was it???
        NSLog("arg klass=%@", [arg class]);  // prints NSCFNumber
    }

    // This check works correctly.
    if ([arg isKindOfClass:[NSArray class]]) {
        for (id x in arg) {
            NSNumber *result = [self doWhatever:x];
            if (result) {
                return result;
            }
        }
    }
    return nil;
}

- (void)someMethod
{
    NSArray *myArray = [NSArray arrayFromObjects:[NSNumber numberWithInt:3], nil]];
    NSNumber *myNum = [self doWhatever:myArray];
    NSLog(@"myNum=%@", myNum);
}

This is obviously a contrived example of what I'm trying to do. The point is this never works b/c the class of "arg" always appears as NSCFNumber, and I can't figure out a way to check for that.

Any way to make it less confusing to detect whether an arbitrary value in an array is an integer or not?


UPDATE: Thanks @chuck, @omz, and @Nikita Leonov for your help. What I posted here originally was just a simplification of the problem I was having and wrote it here without running it first. That code once updated to remove the errors (see below) runs fine actually.

The mistake I made in my real code that I was having trouble with was equally silly--I was passing the array back in to "doWhatever" instead of the item at array's index, which is why I was having problems.

Thanks for trying to help, however misguided my question was. Sorry for wasting everybody's time!

Corrected code that runs as desired:


- (NSNumber *)doWhatever:(id)arg
{
    // this NOW WORKS
    if ([arg isKindOfClass:[NSNumber class]]) {
        return arg;
    }
    else {
        // what was it???
        NSLog(@"arg klass=%@", [arg class]);  // prints NSCFNumber
    }
    
    // This check works correctly.
    if ([arg isKindOfClass:[NSArray class]]) {
        for (id x in arg) {
            NSNumber *result = [self doWhatever:x];
            if (result) {
                return result;
            }
        }
    }
    return nil;
}

- (void)someMethod
{
    NSArray *myArray = [NSArray arrayWithObjects:
                        [NSNumber numberWithInt:1],
                        [NSNumber numberWithInt:2],
                        [NSNumber numberWithInt:3],
                        [NSNumber numberWithInt:4],
                        nil];
    NSNumber *myNum = [self doWhatever:myArray];
    NSLog(@"myNum=%@", myNum);
}
like image 742
jpswain Avatar asked Aug 08 '11 03:08

jpswain


1 Answers

NSCFNumber is a subclass of NSNumber. As long as you're using isKindOfClass: rather than isMemberOfClass: or [arg class] == [NSNumber class], it should work. If not, your problem is elsewhere.

like image 148
Chuck Avatar answered Sep 20 '22 07:09

Chuck