使用NSPredicate进行过滤时返回了非常混乱的结果

时间:2012-01-18 15:37:40

标签: objective-c ios core-data uisearchbar

使用NSPredicate和tableview上的搜索框以及NSFetchedResultsController非常奇怪的结果

它应该基于匹配名称进行过滤...但是,如果我键入任何有效名称,我会得到一些不正确的结果。如果我输入任何全名,如“Mike Johnson”或“Kelly Michaels”,我总会得到“Angelo Smith”的过滤结果。

NSLog将显示  “名字CONTAINS [cd] \”Kelly Michaels \“”

然而,屏幕上显示的过滤结果只显示Angelo Smith?有任何想法如何解决这个问题?

如果您需要有关我正在做的事情的更多详细信息,我一直在使用此堆栈帖子中的解决方案 How to filter NSFetchedResultsController (CoreData) with 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 个答案:

答案 0 :(得分:2)

除非数据集发生变化,否则我不会在过滤时创建新的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];
}