max_
max_

Reputation: 24521

Flawed for loop!

I have a for loop which for some reason wont allow me to delete all objects in an array, only a few.

What am I doing wrong?

- (void)deleteAllObjects {
    AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSLog(@"Before: %d", [histArray count]);
    for (int i = 0; i < [histArray count]; i++) {
        History *h = (History *)[histArray objectAtIndex:i];
        [[appDel managedObjectContext] deleteObject:h];
        [histArray removeObject:h];
        [appDel saveContext];
        NSLog(@"During: %d", [histArray count]);
        [self fetchUpdates];
    }
    NSLog(@"After: %d", [histArray count]);
}

Upvotes: 1

Views: 159

Answers (4)

Tayyab
Tayyab

Reputation: 10651

You are deleting from "histArray" and also you are running your loop on the same array. I think need to reset the indexes after each iteration. Remove the statement "[histArray removeObject:h];" from your loop and at the end of your loop call removeAll function on your array to clear it. It will solve the problem,

Here is the modified code,

- (void)deleteAllObjects {
    AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication] delegate];
    NSLog(@"Before: %d", [histArray count]);
    for (int i = 0; i < [histArray count]; i++) {
        History *h = (History *)[histArray objectAtIndex:i];
        [[appDel managedObjectContext] deleteObject:h];
        [appDel saveContext];
        NSLog(@"During: %d", [histArray count]);
        [self fetchUpdates];
    }
    [histArray removeAllObjects];
    NSLog(@"After: %d", [histArray count]);
}

Upvotes: 1

paxdiablo
paxdiablo

Reputation: 882626

Try changing:

for (int i = 0; i < [histArray count]; i++) {

into:

for (int i = [histArray count] - 1; i >= 0; i--) {

The reason your current loop isn't working is because, when you delete index 0, indexes 1 through 50 don't stay where they are, they shuffle up so that 1 becomes 0, 2 becomes 1 and so on.

So the next time through your loop when you delete index 1, you're leaving the new item at index 0 in there.

By doing the loop backwards, you remove this shuffling and all indexes should be deleted.

Upvotes: 0

Caleb
Caleb

Reputation: 125037

Don't modify an array while you're iterating over its contents. This is particularly important if you're using fast iteration, but it can be a problem even when you're not, as it is here. The issue is that you're changing the positions of the objects by removing objects.

If you must do this, you can:

  • Remove the objects starting from the end of the array and working toward the start, or
  • Don't increase the index. If you remove the object at the beginning of the array for [array count] times, you'll have removed all the objects.

But again, don't change the array if you're using fast iteration or if you're using an enumerator.

Upvotes: 2

Seamus Campbell
Seamus Campbell

Reputation: 17916

You're shortening the array as you loop over it, by calling [histArray removeObject:h]. Since you're removing every object in histArray, why not just wait until after the loop completes and then remove everything at once with [histArray removeAllObjects]?

Another solution is to loop over the array from the end to the beginning.

Upvotes: 4

Related Questions