Search code examples
iphoneobjective-cdynamic-arrays

out of bounds error repopulating array for objective c app (iPhone)


I am currently troubleshooting code written by another colleague that has an out of bounds error with the following code. it involves selecting an item in a UINavigatorController. It also involves use of coreData.

the code looks like this (some of the code had been remove for troubleshooting purposes and clarity)

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

// : so far no errors with these lines of code. indexPath returns [0,0] or [0,1];
NSLog(@" : *** DetailViewController/didSelectRowAtIndexPath() - executing method ..."); 
NSLog(@" : *** DetailViewController/didSelectRowAtIndexPath() - indexPath = %@",indexPath);

// : returns row number (as an integer)

NSLog(@": *** DetailViewController/didSelectRowAtIndexPath() indexPath.row  = %d",indexPath.row);

// : managedObject returns coreData information. 
// Directory *managedObject = (Directory *)[finalArray objectAtIndex:indexPath.row];
// NSLog(@": *** DetailViewController/didSelectRowAtIndexPath() managedObject  = %@",managedObject);

// example return

/* 
  <Directory: 0x5919e50> (entity: Directory; id: 0x59195d0 <x-coredata://FE8A3A0C-A0E4-4E0E-A90D-8471227D2284/Directory/p3> ; data: {
  ID = 48;
  IsFile = 0;
  LastChanged = "2011-01-04 14:39:00 +0000";
  Name = "All Papers by Author";
  ParentID = 7;
  Type = pdf;
  } 
*/

 // : returns the ID value from the managed object
 self.num = [managedObject ID];
 NSLog(@": *** DetailViewController/didSelectRowAtIndexPath() self.num (managedObject.ID)  = %@",[managedObject ID]);


 NSMutableArray *tempArray = [[NSMutableArray alloc] initWithArray:finalArray];

 // : finalArray has two elements when this method runs
 NSLog(@"eja: DetailViewController/didSelectRowAtIndexPath() finalArray length is %i",[finalArray count]);

 [self.finalArray removeAllObjects]; // releases the objects, but makes the array empty;

 // : finalArray after remove all objects runs
 NSLog(@"eja: DetailViewController/didSelectRowAtIndexPath() finalArray length is %i",[finalArray count]);

// ** THE OUT OF BOUNDS ERROR OCCURS HERE **
 [self.finalArray setArray:[self searchDatabase:[self.num intValue] withPredicate:@"ParentID"]];**


 // NSLog(@": DetailViewController/didSelectRowAtIndexPath() finalArray  is %@",self.finalArray); 

// ... more code here, but not relevant.

 // : release the temp NSMutable array

 [tempArray release];

 // : maybe release the finalArray?


}

When I debug the app, I believe finalArray is supposed to be cleared (removeAllObjects) and is supposed to be re-populated, but I get an out of bounds error

Terminating app due to uncaught exception 'NSRangeException', reason: '* -[NSMutableArray objectAtIndex:]: index 1 beyond bounds for empty array'

Not sure where the error is coming from, so looking for some advice and tips...

EDIT: i added a new trace statement after the removeAllObjects statement

// : finalArray after remove all objects runs
 NSLog(@"eja: DetailViewController/didSelectRowAtIndexPath() finalArray length is %i",[finalArray count]);

it returns a count of 0. So should I suspect then that because it has zero length it has no room to reallocate memory to add new items? I thought that was how Mutable arrays work (more or less).

EDIT 2: Instead of setArray, I also tried add ObjectsFromArray, replacing this:

[self.finalArray setArray:[self searchDatabase:[self.num intValue] withPredicate:@"ParentID"]];**

// with this

[self.finalArray addObjectsFromArray:[self searchDatabase:[self.num intValue] withPredicate:@"ParentID"]];

but I had a similar error returned (out of bounds)...


Solution

  • The -setArray: replaces the existing elements with the elements from the array you are passing in. Thus the -removeAllObjects is redundant, but this is not the cause of your problem.

    The size of the array you send -setArray: to is completely irrelevant so the problem probably lies in the array you are getting the elements from i.e. the one you get from:

    [self searchDatabase:[self.num intValue] withPredicate:@"ParentID"]
    

    I would separate that out by assigning a temp variable and then examine it in the debugger before the -setArray: and after the -setArray: (set the option "break on OBjective-C exceptions").