Pedro
Pedro

Reputation: 507

Strange behavior of a FOR loop in objective-C

Found a situation for which I can not find an explanation.

I have an array of arrays in objective-c. this situation the array has 4 empty arrays.

NSArray *dados = [[NSArray alloc] initWithObjects:
             [[NSArray alloc] init],
             [[NSArray alloc] init],
             [[NSArray alloc] init],
             [[NSArray alloc] init],
             nil];

I want a "for" to go through an internal array if it has two or more numbers.

for(int i=0; i<((NSArray *)[dados objectAtIndex:1]).count-1;i++){
        NSLog(@"do anything");
    }

this "for" enter into infinite loop.
However if I use a "NSLog" tells me that the condition is -1, and the "is" not supposed to happen

NSLog(@"%d",((NSArray *)[dados objectAtIndex:1]).count-1);

2014-02-20 15:37:42.563 iKL Time-sheet[31666:a0b] -1

how is it possible that this "for" becomes an infinite loop when the stop condition is 0 <-1?

thought to be a curious case, if someone can explain what is going to be able to better understand the language I thanked

---------------------//----------------
answer:

for(int i=0; i<(int)(((NSArray *)[dados objectAtIndex:1]).count-1);i++){
            NSLog(@"do anything");
        }

with this cast works well, the explanation for this lies in the answer below

Upvotes: 1

Views: 129

Answers (4)

geowar
geowar

Reputation: 4447

NSArray *dados = @[@[],@[],@[]];

// I want a "for" to go through an internal array
// if it has two or more numbers (skipping the last one)
for( NSUInteger idx = 0;
     (dados[1].count >= 2) && (idx < dados[1].count - 1);
     idx++) 
{
    NSLog(@"do anything");
}

Upvotes: 0

Grady Player
Grady Player

Reputation: 14549

your code is not obvious i would re-write with fast iteration

NSArray *dados = [[NSArray alloc] initWithObjects:
         [[NSArray alloc] init],
         [[NSArray alloc] init],
         [[NSArray alloc] init],
         [[NSArray alloc] init],
         nil];

for(NSArray * a in dados)
{
    if([a count] >1)
    {
        NSLog(@"do something");
    }
}

edit:

or

@synchronized(dados){

    for(int i=0; i<[dados count]);i++){
       if([[dados objectAtIndex:i]count]>1)
       NSLog(@"do anything");
    }
}

because you for loop wont make it to the end... you are combining two tests that logically cant be combined... unless your array was sorted by number of elements first.

Upvotes: 2

Merlevede
Merlevede

Reputation: 8170

Remove the -1 from count, otherwise even if you array has many objects it will always skip the last element.

for(int i=0; i<((NSArray *)[dados objectAtIndex:1]).count-1;i++){
        NSLog(@"do anything");
}

Upvotes: 0

Eric Postpischil
Eric Postpischil

Reputation: 222437

count is an unsigned integer (NSUInteger). When the count is zero, subtracting one wraps, producing a large number. Zero is less than a large number.

Upvotes: 9

Related Questions