在 Core Data 中使用搜索栏

Posted

技术标签:

【中文标题】在 Core Data 中使用搜索栏【英文标题】:Using Search bar with Core Data 【发布时间】:2011-10-25 01:49:10 【问题描述】:

我尝试了各种方法,这是我得到的最接近的方法,但是表格的更新使屏幕上的所有条目都变成空白,当我滚动时,它们都变成空白。我还是新手,根本不完全确定要在核心数据表视图上实现搜索。

如果我不把东西清零,它就会死在这里:

更新:这是我现在正在尝试的,我遇到了同样的崩溃: Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no section at index 1'

`Recipe *recipe = (Recipe *)[fetchedResultsController objectAtIndexPath:indexPath];` **`Thread 1 received signal SIGABRT`**


#pragma mark -
#pragma mark search bar methods
- (void) searchBarSearchButtonClicked:(UISearchBar *)searchBar 
    NSLog(@"searched");
    fetchedResultsController = nil;       
    //============
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Recipe" inManagedObjectContext:managedObjectContext];

    if (searchBar.text !=nil) 
        NSPredicate *predicate =[NSPredicate predicateWithFormat:@"name contains[cd] %@", searchBar.text];
        [fetchedResultsController.fetchRequest setPredicate:predicate];
     else 
        NSPredicate *predicate =[NSPredicate predicateWithFormat:@"All"];
        [fetchedResultsController.fetchRequest setPredicate:predicate];
    

    [fetchRequest setEntity:entity];

    // Edit the sort key as appropriate.
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"state" ascending:YES];// was name
    NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];

    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor,sortDescriptor2, nil];// was 2

    [fetchRequest setSortDescriptors:sortDescriptors];

    // Edit the section name key path and cache name if appropriate.
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"state" cacheName:@"Root"];//@"state"
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    [aFetchedResultsController release];
    [fetchRequest release];
    [sortDescriptor release];
    [sortDescriptor2 release];
    [sortDescriptors release];
    //==============

    // dismiss the search keyboard
    [searchBar resignFirstResponder];

    // reload the table view
    //[self.tableView reloadData];




- (void)configureCell:(RecipeTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath 
    // Configure the cell //DIES HERE
    Recipe *recipe = (Recipe *)[fetchedResultsController objectAtIndexPath:indexPath];
    cell.recipe = recipe;

在其他情况下,当我尝试向上或向下移动桌子时它会死机。

感谢您在理解和解决此问题方面提供的任何指导或帮助!

罗伯

tableViewController.m

- (NSFetchedResultsController *)fetchedResultsController 
    if (fetchedResultsController == nil) 
        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
        NSEntityDescription *entity = [NSEntityDescription entityForName:@"Recipe" inManagedObjectContext:managedObjectContext];
        [fetchRequest setEntity:entity];

        // Edit the sort key as appropriate.
        NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"state" ascending:YES];// was name
        NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];

        NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor,sortDescriptor2, nil];// was 2

        [fetchRequest setSortDescriptors:sortDescriptors];

        // Edit the section name key path and cache name if appropriate.
        NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"state" cacheName:@"Root"];//@"state"
        aFetchedResultsController.delegate = self;
        self.fetchedResultsController = aFetchedResultsController;

        [aFetchedResultsController release];
        [fetchRequest release];
        [sortDescriptor release];
        [sortDescriptor2 release];
        [sortDescriptors release];
    
    return fetchedResultsController;
 

- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar 
    self.fetchedResultsController = nil;

    self.searchBar.text=@"";

    [self.searchBar setShowsCancelButton:NO animated:YES];
    [self.searchBar resignFirstResponder];
    //self.tableView.allowsSelection = YES;
    //self.tableView.scrollEnabled = YES;

- (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar 
    // added 2 below
    //self.fetchedResultsController.delegate = nil;
    self.fetchedResultsController = nil;
    [self.searchBar setShowsCancelButton:YES animated:YES];
    //self.tableView.allowsSelection = NO;
    //self.tableView.scrollEnabled = NO;


- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar 
    // added 2 below
    //self.fetchedResultsController.delegate = nil;
    self.fetchedResultsController = nil;
    NSLog(@"fetchObjects");
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Recipe" inManagedObjectContext:managedObjectContext];
    [fetchRequest setEntity:entity];

    // Edit the sort key as appropriate.
    //NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"state" ascending:YES];// was name
    NSSortDescriptor *sortDescriptor2 = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];

    //NSLog(@"NSInteger value :%@", sortDescriptor);
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor2, nil];

    [fetchRequest setSortDescriptors:sortDescriptors];

    // perform query
    NSString *query = self.searchBar.text;
    if (query && query.length) fetchRequest.predicate = [NSPredicate predicateWithFormat:@"name CONTAINS[cd] %@", query];


    // Edit the section name key path and cache name if appropriate.
    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:managedObjectContext sectionNameKeyPath:@"state" cacheName:@"Root"];//@"state"
    aFetchedResultsController.delegate = self;
    self.fetchedResultsController = aFetchedResultsController;

    [aFetchedResultsController release];
    [fetchRequest release];
    //[sortDescriptor release];
    [sortDescriptor2 release];
    [sortDescriptors release];
    //[self.tableView reloadData];
   

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller 
    // The fetch controller is about to start sending change notifications, so prepare the table view for updates.
    [self.tableView beginUpdates];

【问题讨论】:

【参考方案1】:

看起来您实际上从未执行过获取请求。来自docs:

创建实例后,调用 performFetch: 执行提取。

【讨论】:

如:NSError *error; BOOL success = [fetchedResultsController performFetch:&error];? 是的。如果你不这样做,你将不会得到任何结果。 无论我是否执行搜索,应用程序都会在配置单元格上崩溃...感谢 performFetch 提示! .. 仍在学习,有趣但令人沮丧。 崩溃时显示什么? 您使用的是具有配方属性的自定义 UITableViewCell 吗?【参考方案2】:

你在使用 UISearchDisplayController 吗?如果你是你最终得到两张表:一张显示你的正常东西,另一张与搜索相关。您必须分别处理这些表。

在How to filter NSFetchedResultsController (CoreData) with UISearchDisplayController/UISearchBar 处有一份关于实现表搜索所需的所有代码的文章

【讨论】:

我重读了几次,但我仍然不知道@interface BlahViewController () ATproperty (nonatomic, retain) NSFetchedResultsController *fetchedResultsController; ATproperty(非原子,保留) NSFetchedResultsController *searchFetchedResultsController; ATproperty(非原子,保留) UISearchDisplayController *mySearchDisplayController; ATend 实施 它们是合成的,并且在链接的答案中拼出了吸气剂。

以上是关于在 Core Data 中使用搜索栏的主要内容,如果未能解决你的问题,请参考以下文章

最近使用 Core Data 进行的搜索

使用标签助手调用控制器,包括来自 asp.net core mvc 中搜索栏的数据

在 Core Data 上创建一个关键字结构并搜索那个大动物

(Swift) 如何对 Core Data 进行模糊搜索?

如何过滤在 Core Data 中有对象的表视图?

如何在重新进入查看时转储 Core Data 搜索结果 FRC?