2009-08-27 2 views
0

У меня есть tableview с navigationBar с сегментированным контролем в верхней части представления. Я установил segmentedControl с кнопками, которые сортируют таблицу с помощью «FirstName» или «LastName». Он отлично работает в первые 2-4 раза, когда вы нажимаете кнопки сортировки, но затем приложение падает.Таблица сбоев при сортировке данных несколько раз

Отладчик и консоль, похоже, не помогают найти источник ошибки. Кто-нибудь видит вопиющие ошибки в моем коде?

Вот мой код ниже, дайте мне знать, если у вас есть вопросы. Благодаря!

- (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

Не отпускать eachItemList в конце вашей петли. Вы явно не выделили его в этом контексте, поэтому его не следует выпускать.

Цикл for (object in array) дает вам ссылку на объект в массиве, а не на копию. Отправляя сообщение освобождения на эту ссылку, вы уменьшаете счетчик сохранения этого объекта, пока он все еще находится в массиве. Через несколько раз (в зависимости от того, сколько раз объект был сохранен, NSArray, например, сохраняет объекты, когда они добавляются в массив), счетчик будет достигнут 0, и затем он будет освобожден, и вы получите сбои в отношении нераспознанных селекторы или EXC_BAD_ACCESS и, возможно, другие виды ошибок.

+0

Отлично! Это позволило мне переключить методы сортировки примерно 6 раз перед сбоем - определенное улучшение. Затем я прекратил выпуск tempSectionedDictionaryByFirstLetter, и теперь он отлично работает. Это, похоже, идет против управления памятью, так как я выделил его. Любая идея, где его выпустить? Спасибо! – Jonah

Смежные вопросы