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

1

6

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);
}
Seismoscope answered 8/8, 2011 at 3:51 Comment(3)
Are you sure that you build an array i such way? I wrote following code an isKindOfClass works well in this case: NSNumber *number = [NSNumber numberWithFloat:0.5]; if ([number isKindOfClass:[NSNumber class]]) { NSLog(@"NSNumebr"); }Hebron
Checked initialization of array as shown in your "someMethod to os also works as expected for isKindOfClass call.Hebron
Did you really use this exact code? There is no arrayFromObjects: method, it's called arrayWithObjects:. Except for that, it should work and print NSCFArray (or something similar) instead of NSCFNumber.Lenardlenci
R
10

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.

Rodina answered 8/8, 2011 at 16:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.