使用 NSPredicate 进行核心数据实体搜索
Posted
技术标签:
【中文标题】使用 NSPredicate 进行核心数据实体搜索【英文标题】:Core Data Entity Search Using NSPredicate 【发布时间】:2014-08-06 11:47:38 【问题描述】:我有一个将数据保存到 Core Data sql 的应用程序,然后在 tableView
中查看它。我正在尝试添加searchBar
来搜索数据。
我创建了两个NSFetchedResultsController
。一个用于获取实体数据,另一个用于使用NSPredicate
过滤后获取实体数据。
- (NSFetchedResultsController *)fetchedResultsController
if (_fetchedResultsController != nil)
return _fetchedResultsController;
CoreDataStack *coreDataStack = [CoreDataStack DefaultStack];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"offer" inManagedObjectContext:coreDataStack.managedObjectContext];
[fetchRequest setEntity:entity];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO]];
_fetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:coreDataStack.managedObjectContext sectionNameKeyPath:@"sectionName" cacheName:nil];
_fetchedResultsController.delegate = self;
return _fetchedResultsController;
- (NSFetchedResultsController *)fetchedSearchResultsController
if (_fetchedSearchResultsController != nil)
return _fetchedSearchResultsController;
CoreDataStack *coreDataStack = [CoreDataStack DefaultStack];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"offer" inManagedObjectContext:coreDataStack.managedObjectContext];
[fetchRequest setEntity:entity];
fetchRequest.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"date" ascending:NO]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"location contains[c] %@", self.searchDisplayController.searchBar.text];
[fetchRequest setPredicate:predicate];
_fetchedSearchResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:coreDataStack.managedObjectContext sectionNameKeyPath:@"sectionName" cacheName:nil];
_fetchedSearchResultsController.delegate = self;
return _fetchedSearchResultsController;
并通过cellForRowAtIndexPath
显示每个单元格中的数据:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];//] forIndexPath:indexPath];
if (cell == nil)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
Entry *entry = [self.fetchedResultsController objectAtIndexPath:indexPath];
Entry *searchEntry = [self.fetchedSearchResultsController objectAtIndexPath:indexPath];
NSString *recipe = nil;
if (tableView == self.searchDisplayController.searchResultsTableView)
cell.textLabel.text = searchEntry.location;
else
cell.textLabel.text = entry.location;
return cell;
但我收到此错误:*'NSRangeException',原因:'* -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'*
当我将 [fetchRequest setPredicate:predicate]; 注释掉时,我不再收到错误消息。所以我假设错误来自谓词,但我不知道如何克服它。
【问题讨论】:
【参考方案1】:Entry *entry = [self.fetchedResultsController objectAtIndexPath:indexPath]; 条目 *searchEntry = [self.fetchedSearchResultsController objectAtIndexPath:indexPath]; 首先检查 entry 和 searchEntry 是否返回 null ?
【讨论】:
我查过了。我发现 searchEntry 正在返回 null。 这就是您遇到此错误的原因。现在检查 _fetchedSearchResultsController 值是否为零 - (NSFetchedResultsController *)fetchedSearchResultsController 抱歉,好像我检查 searchEntry 的方式有误。现在我所做的是NSLog(@"Checking searchEntry"); if ([searchEntry isEqual:[NSNull null]]) NSLog(@"searchEntry is null");
我没有日志。
亲爱的只需添加 NSLog(@"search entry is %@", searchEntry);并检查 searchEntry 的值以上是关于使用 NSPredicate 进行核心数据实体搜索的主要内容,如果未能解决你的问题,请参考以下文章
使用 NSPredicate 对表视图中的核心数据进行排序 (Swift)
带有核心数据的 NSPredicate,在字符串属性中搜索带有边界的单词