核心数据:使用 SQLITE 存储类型时,包含对多关系的 NSPredicate 不会产生任何结果
Posted
技术标签:
【中文标题】核心数据:使用 SQLITE 存储类型时,包含对多关系的 NSPredicate 不会产生任何结果【英文标题】:Core Data: NSPredicate containing to-many relationship yields no results when using SQLITE store type 【发布时间】:2011-01-24 16:18:40 【问题描述】:直到最近,我一直在为我的项目使用带有内存存储的 Core Data。现在我正在尝试切换到 SQLite 商店,但遇到了以下问题:
当尝试使用谓词和 sortDescriptor 从存储中获取对象时,我的 fetchedResultsController 返回 0 个对象。当存储类型为内存时,完全相同的代码可以正常工作。
这就是我进行抓取的方式:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"ANY %K == %@", @"categories", category];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"title" ascending:YES selector:@selector(caseInsensitiveCompare:)];
self.fetchedResultsController = [self createFetchedResultsControllerWithEntityName : @"Provider" sectionName : @"group" sortDescriptor : sortDescriptor predicate : predicate cache : nil];
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error])
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
[self.tableView reloadData];
这是我创建获取请求的地方:
- (NSFetchedResultsController *)createFetchedResultsControllerWithEntityName : (NSString*) entityName sectionName : (NSString*) sectionName sortDescriptor : (NSSortDescriptor*) sortDescriptor predicate : (NSPredicate*) predicate cache : (NSString*) cacheName
// Create the fetch request for the entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
//set predicate
if (predicate)
[fetchRequest setPredicate:predicate];
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:sectionName
cacheName:cacheName];
aFetchedResultsController.delegate = self;
[fetchRequest release];
[sortDescriptor release];
[sortDescriptors release];
return [aFetchedResultsController autorelease];
同样,同样的代码在使用内存存储时会获取许多对象,但在使用 SQLite 时会获取一个空的 fetchedObjects 数组。
我已经阅读了 Apple 的文档,了解在 SQLite 存储中使用谓词和 sortDescritors 时要考虑的特殊注意事项。我在谓词中使用单个(多)对多关系(类别),所以这应该没问题吗?
提取没有返回错误。根本没有对象(fetchedResultsController.fetchedObjects 是空的)。
任何指导将不胜感激。
谢谢
【问题讨论】:
【参考方案1】:我终于弄清楚了这个问题。
我的查询没有返回结果,确实没有结果。追溯到我创建对象并用值填充关系的地方,我注意到我做错了。我试着做:
[provider.categories addObject : newCategory];
这并没有真正将 newCategory 添加到类别关系中。 在意识到 Core Data 会自动生成对多关系的访问器后,我使用以下内容添加了 newCategory:
[provider addCategoriesObject : newCategory];
这会正确地将 newCategory 添加到关系中。
除此之外,我在 Provider.h 中声明了 addCategoriesObject 以抑制编译器警告。这为我解决了这个问题。
唯一剩下的警告是编译器没有找到 addCategoriesObject: 的实现,并警告“不完整的实现”。我还没有想出办法来抑制这个警告。
【讨论】:
【参考方案2】:我知道 SQLite 存储在某些情况下会遇到 "ANY"
提取问题(我不记得确切的那些)。也许尝试修改你的搜索谓词,看看你是否得到不同的结果,例如
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"categories LIKE %@", category];
【讨论】:
以上是关于核心数据:使用 SQLITE 存储类型时,包含对多关系的 NSPredicate 不会产生任何结果的主要内容,如果未能解决你的问题,请参考以下文章
预填充核心数据存储:使用 JSON 属性列表还是 XML 文件?