Результаты индексирования от NSFetchedResultsController

У меня есть некоторые проблемы со смешанными, индексированными, доступными для поиска результатами, установленными из контроллера NSFetchedResults. Я настроил его для хранения сначала индексированных инициалов AZ для объекта, а затем хочу, чтобы он отображал первые числовые инициалы (то есть #, как это делает UILocalizedIndexCollation).

Я уже написал код, который сохраняет атрибут "firstInitial" объекта Artist как NSString @ "#", если полное имя начинается с числа, и мне кажется, что код наполовину работает в моем UITableViewController с настраиваемый дескриптор сортировки. Проблема в том, что он работает только до тех пор, пока я не выйду / не перезапущу приложение.

На этом этапе вверху появляется раздел # из полученных результатов. Он будет оставаться там до тех пор, пока я не принудительно изменю данные (добавлю / удалю управляемый объект), а затем найду запись и очисту поиск (с помощью searchDisplayController). На этом этапе начнется изменение порядка разделов, а раздел # будет перемещен в конец ...

Я явно чего-то упускаю / слишком долго смотрел на один и тот же код. В качестве альтернативы, есть гораздо более простой способ сделать это, о котором я не знаю / не могу найти в Google!

Любая помощь приветствуется!

Спасибо

Шон

Соответствующий код из моего Ниже приведен UITableViewController.

- (void)viewDidLoad
{
    // ----------------------------------
    // Various other view set up things in here....
    // ...
    // ...
    // ----------------------------------

    NSError *error;
    if (![[self artistResultsController] performFetch:&error]) {
        // Update to handle the error appropriately.
        NSLog(@"Failed to fetch artists: %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }

}
- (NSFetchedResultsController *)artistResultsController {

if (_artistResultsController != nil) {
    return _artistResultsController;
}

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription 
                               entityForName:@"Artist" inManagedObjectContext:_context];
[fetchRequest setEntity:entity];

NSSortDescriptor *initialSort = [[NSSortDescriptor alloc] 
                          initWithKey:@"firstInitial" 
                          ascending:YES 
                          comparator:^(id obj1, id obj2) {
                              // Various number conditions for comparison - if it's a # initial, then it's a number
                              if (![obj1 isEqualToString:@"#"] && [obj2 isEqualToString:@"#"]) return NSOrderedAscending;
                              else if ([obj1 isEqualToString:@"#"] && ![obj2 isEqualToString:@"#"]) return NSOrderedDescending;
                              if ([obj1 isEqualToString:@"#"] && [obj2 isEqualToString:@"#"]) return NSOrderedSame;
                              // Else it's a string - compare it by localized region
                              return [obj1 localizedCaseInsensitiveCompare:obj2];
                          }];

NSSortDescriptor *nameSort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];

[fetchRequest setSortDescriptors:[NSArray arrayWithObjects:initialSort, nameSort, nil]];

[fetchRequest setFetchBatchSize:20];

NSFetchedResultsController *theFetchedResultsController = 
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
                                    managedObjectContext:_context 
                                      sectionNameKeyPath:@"firstInitial" 
                                               cacheName:nil];
self.artistResultsController = theFetchedResultsController;
_artistResultsController.delegate = self;

[nameSort release];
[initialSort release];
[fetchRequest release];
[_artistResultsController release];

return _artistResultsController;}

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return nil;
    } else {
        return [[[_artistResultsController sections] objectAtIndex:section] name];
    }
}

- (NSArray *)sectionIndexTitlesForTableView:(UITableView *)tableView
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return nil;
    } else {
        return [[NSArray arrayWithObject:UITableViewIndexSearch] arrayByAddingObjectsFromArray:
                [[UILocalizedIndexedCollation currentCollation] sectionIndexTitles]];

    }
}

- (NSInteger)tableView:(UITableView *)tableView sectionForSectionIndexTitle:(NSString *)title atIndex:(NSInteger)index
{
    if (tableView == self.searchDisplayController.searchResultsTableView) {
        return 0;
    } else {
        if (title == UITableViewIndexSearch) {
            [tableView scrollRectToVisible:self.searchDisplayController.searchBar.frame animated:NO];
            return -1;
        } 
        else {
            for (int i = [[_artistResultsController sections] count] -1; i >=0; i--) {
                NSComparisonResult cr = 
                [title localizedCaseInsensitiveCompare:
                 [[[_artistResultsController sections] objectAtIndex:i] indexTitle]];
                if (cr == NSOrderedSame || cr == NSOrderedDescending) {
                    return i;
                }
            }
            return 0;
        }
    }
}

РЕДАКТИРОВАТЬ: Забыл упомянуть - мой поисковый фильтр использует предикат на контроллере fetchedResults, поэтому это вызывает новый запрос на выборку, например

- (void)filterContentForSearchText:(NSString*)searchText scope:(NSString*)scope {
    NSFetchRequest *aRequest = [_artistResultsController fetchRequest];

    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name BEGINSWITH[cd] %@", searchText];
    // set predicate to the request 
    [aRequest setPredicate:predicate];
    // save changes
    NSError *error = nil;
    if (![_artistResultsController performFetch:&error]) {
        NSLog(@"Failed to filter artists: %@, %@", error, [error userInfo]);
        abort();
    }  
} 
5
задан Sean Bedford 15 May 2011 в 20:40
поделиться