-1

I'm comparing two NSUInteger, I kept getting crash thats says -[__NSCFNumber length]: unrecognized selector sent to instance

NSUInteger index = [masterArray indexOfObject:object];
if (index != NSNotFound){
    if (index < [anArray  count] - 1 ){
        //Do something
    }
    else{
        //Do something
    }
}

Reading old post of similar question, but I still can't figure this out. I've tried to cast and it still crash:

NSUInteger index = [masterArray indexOfObject:object];
if (index != NSNotFound){
    if (index < (NSUInteger)((int)[anArray  count] - 1) ){
        //Do something
    }
    else{
        //Do something
    }
}

However, without any minus operation, it works.

NSUInteger index = [masterArray indexOfObject:object];
if (index != NSNotFound){
    if (index < [anArray  count]){
        //Do something
    }
    else{
        //Do something
    }
}

Any idea why? Thanks in advance.

Gregor Isack
  • 1,111
  • 12
  • 25
  • Is the `-[__NSCFNumber length]` crash in this code or in `//Do something`? Is the class of the result of `anArray[count - 1]` a `NSNumber` while you're expecting a `NSString`? – Willeke Aug 09 '20 at 09:56
  • I think the crash happens in the ‘// Do something’ part. You are doing that if ‘index < [array count] - 1‘ and I think the array is empty. However, because it is unsigned, 0-1 wraps to a huge positive and you go down the wrong branch. Maybe change the compare to ‘index + 1 < [array count]’ and see what happens. – skaak Aug 09 '20 at 12:15
  • You guys are right, after rechecking my code based on the opinions, I found that `anArray` is an empty array on some instances, causing subsequent code to crash. Thanks! I'll be closing this post as it's not related to the question anymore. – Gregor Isack Aug 09 '20 at 12:21

1 Answers1

-1

the array is not the problem. See what happens in the following example.

NSUInteger i = 0;
NSLog(@"%@", i-1==NSUIntegerMax ? @"YES" : @"NO" );
//output: YES

NSLog(@"NSUIntegerMax=%lu", NSUIntegerMax );
//output: NSUIntegerMax=18446744073709551615

NSLog(@"%lu", i-1 );
//output: 18446744073709551615

so when array count is 0 and you subtract 1 you end up with the NSUIntegerMax.

You compare array.count - 1 against a range of numbers that can't express signed (negative) numbers.

array.count is a property of type NSUInteger.
so in the following scenario will come up

when array.count == 0,

array.count - 1 == 18446744073709551615 // not!! -1

your if statements will not work as expected unless you really wanted to compare to NSUIntegerMax. As you discovered casting to integer may help you out..
you will want to

if (index < ((int)array.count) - 1) {
} else {
}

because casting (NSUInteger)((int)array.count - 1)
is still 18446744073709551615 == NSUIntegerMax when array.count < 1

you could also go without casting for this solution

if (index + 1 >= array.count) {
} else {
}
Ol Sen
  • 3,163
  • 2
  • 21
  • 30