Очень запутанные результаты, возвращаемые при фильтрации с NSPredicate - PullRequest
0 голосов
/ 18 января 2012

Очень странные результаты с использованием NSPredicate в сочетании с полем поиска в табличном представлении и NSFetchedResultsController

Предполагается, что это фильтрация на основе совпадения имени ... однако, если я введу любое допустимое имя, я получу несколько результатов, которые просто не верны. Если я вписываю любое полное имя, например «Майк Джонсон» или «Келли Майклз», я всегда получаю один и тот же отфильтрованный результат «Анджело Смита».

NSLog покажет "name CONTAINS [cd] \" Kelly Michaels \ ""

И все же отфильтрованный результат, отображаемый на экране, покажет только Анджело Смита? Есть идеи, как решить эту проблему?

Я использовал решение в этом сообщении, если вам нужно больше подробностей о том, что я делаю Как отфильтровать NSFetchedResultsController (CoreData) с помощью UISearchDisplayController / UISearchBar

- (NSFetchedResultsController *)newFetchedResultsControllerWithSearch:(NSString *)searchString
{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];

NSPredicate *filterPredicate = nil;

/*
 Set up the fetched results controller.
 */
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.

NSEntityDescription *entity = [NSEntityDescription entityForName:@"Staff" inManagedObjectContext:self.managedObjectContext];

[fetchRequest setEntity:entity];

NSMutableArray *predicateArray = [NSMutableArray array];

if(searchString.length)
{
    NSLog(@"here searchString is %@", searchString);

    // your search predicate(s) are added to this array
    [predicateArray addObject:[NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@", searchString]];
    // finally add the filter predicate for this view

    NSLog(@"%@", predicateArray);

    if(filterPredicate)
    {
        filterPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:[NSArray arrayWithObjects:filterPredicate, [NSCompoundPredicate orPredicateWithSubpredicates:predicateArray], nil]];
    }
    else
    {
        filterPredicate = [NSCompoundPredicate orPredicateWithSubpredicates:predicateArray];
    }
}


   [fetchRequest setPredicate:filterPredicate];
...

1 Ответ

2 голосов
/ 18 января 2012

Я бы не стал создавать новый FRC при фильтрации, если только набор данных не меняется. Вместо этого просто измените предикат и выполните другую выборку (в пользовательском методе, называемом что-то вроде filterContentForSearchText)

Пример:

-(void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{   
    [self filterContentForSearchText:searchText];   
}

-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
    searchBar.text = @"";
    NSPredicate *predicate = nil;
    [self.fetchedResultsController.fetchRequest setPredicate:predicate];
    [self.fetchedResultsController.fetchRequest setFetchLimit:0];  // 0 is no limit

    [searchBar resignFirstResponder];
    NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) {
        // Handle error
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  //
    }
    [self.myTableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];

}

- (void)filterContentForSearchText:(NSString*)searchText
{
    NSString *query = searchText;
    if (query && query.length) {
        NSPredicate *predicate = [NSPredicate predicateWithFormat:@"name contains[cd] %@ or department contains[cd] %@", query, query];
        [self.fetchedResultsController.fetchRequest setPredicate:predicate];
        [self.fetchedResultsController.fetchRequest setFetchLimit:100];  // I use 100 because of the large dataset I am working with (4500 records)
    }

    NSError *error = nil;
    if (![[self fetchedResultsController] performFetch:&error]) {
        // Handle error
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        exit(-1);  // Fail
    }  
    [self.myTableView performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:NO];
}

-(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
    [self filterContentForSearchText:searchBar.text];
    [searchBar resignFirstResponder];
}
...