views:

113

answers:

1

I have a tableview with a navigationBar with a segmentedControl on the top of the view. I have set up the segmentedControl with buttons that sort the table by either "FirstName" or "LastName". It works perfectly the first 2-4 of times you press the sorting buttons, but then the app crashes.

The debugger and console seem to be of no help finding the source of the bug. Does anyone see any glaring mistakes in my code?

Here is my code below, let me know if you have any questions. Thanks!

- (IBAction)sortingSegmentAction:(id)sender{

NSString *keyToSortBy = [NSString alloc];

if([sender selectedSegmentIndex] == 0)
{
 self.sortingSegmentActionPressed = 0;
 keyToSortBy = @"FirstName";
}
else if([sender selectedSegmentIndex] == 1)
{
 self.sortingSegmentActionPressed = 1;
 keyToSortBy = @"LastName";
}

 //Create the sort descriptors
 NSSortDescriptor *sortDescriptor = [[[NSSortDescriptor alloc] initWithKey:keyToSortBy ascending:YES] autorelease];
 NSArray *sortDescriptors = [NSArray arrayWithObject:sortDescriptor];

 //Sort allSubItams by the values set in the sort descriptors
 NSArray *sortedArray;
 self.sortedArray = [allSubItems sortedArrayUsingDescriptors:sortDescriptors];

 //Recreate the data structure by putting the newly sorted items into a dictionary sorted by inital letters.
 NSDictionary *eachItemList;  //A DICTIONARY FOR PUTTING ALL THE DATA FOR EACH ITEM IN IT'S OWN SECTION
 NSMutableDictionary *tempSectionedDictionaryByFirstLetter = [[NSMutableDictionary alloc] init];

 for (eachItemList in sortedArray) //eachElementList is a dictionary with a section for each item
 {
  NSDictionary *aDictionary = [[NSDictionary alloc] initWithDictionary:eachItemList];
  NSString *firstLetterString;
  firstLetterString = [[aDictionary valueForKey:keyToSortBy]substringToIndex:1];
  NSMutableArray *existingArray;
  if (existingArray = [tempSectionedDictionaryByFirstLetter valueForKey:firstLetterString]) 
  {
   [existingArray addObject:eachItemList];
  } else {
   NSMutableArray *tempArray = [NSMutableArray array];
   [tempSectionedDictionaryByFirstLetter setObject:tempArray forKey:firstLetterString];
   [tempArray addObject:eachItemList];
  }
  [aDictionary release];
  [eachItemList release];
 }

 //Set the data source for the table (sectionedDictionaryByFirstLetter) to tempSectionedDictionaryByFirstLetter.
    self.sectionedDictionaryByFirstLetter = tempSectionedDictionaryByFirstLetter;
 NSMutableArray *keyArray = [[NSMutableArray alloc] init];
 [keyArray addObjectsFromArray:[[self.sectionedDictionaryByFirstLetter allKeys] sortedArrayUsingSelector:@selector(compare:)]];
 self.keys = keyArray;

 [self.tableView reloadData];

 [keyArray release];
 [tempSectionedDictionaryByFirstLetter release];

}
+1  A: 

Don't release eachItemList at the end of your loop. You did not explicitly allocate it in this context so you shouldn't release it.

The for (object in array) loop gives you a reference to the object in the array, not a copy. By sending a release message to this reference, you are decrementing the retain count of this object while it is still in the array. After a few times (depending on how many times the object has been retained, NSArray for example retains objects when they are added to the array) it's retain count will reach 0, and it will then become deallocated and you'll get crashes regarding unrecognised selectors or EXC_BAD_ACCESS and possibly other kinds of errors.

dreamlax
Great! That enabled me to switch sorting methods about 6 times before crashing- a definite improvement. I then stopped releasing the tempSectionedDictionaryByFirstLetter and it now works perfectly. This seems to go against memory management since I've allocated it. Any idea where to release it?Thanks!
Jonah