0

I'm using AFNetworking along with FMDB to remove database rows from an array when I make a successful POST to a server. My problem at the moment is that my logging shows that I'm skipping every second item in the array, so I think I've incorrectly used FMDB in conjunction with AFNetworking's async request.

This is what the code looks like:

[manager POST:[_urlEndpoint absoluteString] parameters:data success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"JSON: %@", responseObject);
    [_dbQueue inDatabase:^(FMDatabase *db) {
        for (int i = 0; i < arrayOfIds.count; ++i)
        {
            NSLog(@"Removing event at index: %@", arrayOfIds[i]);
            [_db removeWithId:arrayOfIds[i]];
        }
    }];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

In the arrayOfIds, the logs shows that I hit 1, skip 2, hit 3, skip 4, etc. In this particular case, I've made sure I'm only sending one POST request so narrow down the root cause so I know there aren't multiple accesses to arrayOfIds.

What could I have done wrong that I may have missed?

(Possibly) related question I just asked before: FMDB: Does calling a method to make a query in the inDatabase block work the same way?

EDIT: Here are what my logs look like..

2014-07-13 03:08:28.684 PostTestApp[77268:6675567] Adding event to array to be sent: 1
2014-07-13 03:08:28.684 PostTestApp[77268:6675567] Adding event to array to be sent: 2
2014-07-13 03:08:28.684 PostTestApp[77268:6675567] Adding event to array to be sent: 3
2014-07-13 03:08:28.684 PostTestApp[77268:6675567] Adding event to array to be sent: 4
2014-07-13 03:08:28.684 PostTestApp[77268:6675567] Adding event to array to be sent: 5
2014-07-13 03:08:28.684 PostTestApp[77268:6675567] Adding event to array to be sent: 6
2014-07-13 03:08:29.191 PostTestApp[77268:6675567] JSON: {
    description = "Server response from /events";
    name = response;
}
2014-07-13 03:08:29.192 PostTestApp[77268:6675567] Removing event at index: 1
2014-07-13 03:08:29.192 PostTestApp[77268:6675567] Removed event from row: 1
2014-07-13 03:08:29.195 PostTestApp[77268:6675567] Removing event at index: 3
2014-07-13 03:08:29.195 PostTestApp[77268:6675567] Removed event from row: 3
2014-07-13 03:08:29.196 PostTestApp[77268:6675567] Removing event at index: 5
2014-07-13 03:08:29.197 PostTestApp[77268:6675567] Removed event from row: 5
  • "Adding event to array to be sent:" is a for-loop that adds database IDs into arrayOfIds.
  • "Removing event at index:" happens inside the inDatabase: block.
  • "Removed event from row:" happens inside removeWithId:.

EDIT 2:

Full code block without edits: https://gist.github.com/jonalmeida/27bee72b9015d45434e8

Community
  • 1
  • 1
jonalmeida
  • 1,206
  • 1
  • 9
  • 24
  • I don't think it's an AFNetworking issue. AFNetworking completion blocks are all called on the main thread. What is `_db` and why not use `db`? Is `_db` a different `FMDatabase` than `db`? What logs are you talking about? Can you post their actual output? – Aaron Brager Jul 13 '14 at 07:02
  • `_db` is my wrapper class around the `FMDatabase`. It just does a `[FMDatabase open]` check before executing the DELETE query using `removeWithId:`. I'll update the question with the logs, give me a sec. – jonalmeida Jul 13 '14 at 07:06
  • Is the problem that your conditional is `i < arrayOfIds` instead of `i < arrayOfIds.count`? – Aaron Brager Jul 13 '14 at 07:15
  • It seems too consistent a problem for that to actually be the cause, so I'm assuming that's an effect of simplifying your code for this question. – Aaron Brager Jul 13 '14 at 07:17
  • No, it actually is arrayOfIds.count, I changed the variable names to make them easier to read. Fixed that now! – jonalmeida Jul 13 '14 at 07:17
  • @AaronBrager yeah, I'm guessing it's just user error on my behalf. I just can't tell where... I've stared at this block for a while now. – jonalmeida Jul 13 '14 at 07:18
  • It looks like either the adding code (not shown) is wrong (your array actually has 1, 3, 5, 7, etc.), or that the deleting has some effect on the ID array. – Aaron Brager Jul 13 '14 at 07:19
  • I've added the actual code in a gist on the post as well. It's a bit messy so I apologize for that. The adding has to be correct since I can see from the logs that it is added correctly. If I run this code block again, it sends the remaining items then (in the same fashion). – jonalmeida Jul 13 '14 at 07:24

1 Answers1

1

According to your gist, your actual code looks like this:

for (int i=0; i < dbIndexArray.count; i++) {
    NSLog(@"Removing event at index: %@", dbIndexArray[i]);
    [_db removeEventWithId:[[dbIndexArray objectAtIndex:i] longLongValue]];
    [dbIndexArray removeObjectAtIndex:i];
}

The problem is: you are modifying the array while you're iterating through it. When you remove object 0, and object 1 becomes object 0.

Try this:

NSMutableArray *removedIDs = [NSMutableArray array];

for (int i=0; i < dbIndexArray.count; i++) {
    NSLog(@"Removing event at index: %@", dbIndexArray[i]);
    [_db removeEventWithId:[[dbIndexArray objectAtIndex:i] longLongValue]];
    [removedIDs addObject:dbIndexArray[i];
}

[dbIndexArray removeObjectsInArray:removedIDs];
Aaron Brager
  • 65,323
  • 19
  • 161
  • 287