核心数据:使用 SQLITE 存储类型时,包含对多关系的 NSPredicate 不会产生任何结果
直到最近,我一直在我的项目中使用带有内存存储的核心数据。现在我尝试切换到 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 存储中使用谓词和 sortDescriptor 时要考虑的特殊注意事项。我在谓词中使用单个(多)对多关系(类别),所以这应该没问题吗?
获取过程中没有返回任何错误。根本没有对象(fetchedResultsController.fetchedObjects 为空)。
任何指导将不胜感激。
谢谢
I have been using Core Data with In-Memory store for my project until recently. Now I am trying to switch to SQLite store and I'm facing the following issue:
When Trying to fetch objects from the store using a predicate and sortDescriptor, my fetchedResultsController returns 0 objects. The exact same code works fine when the store type is in-memory.
This is how I am making the fetch:
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];
and this is where I create the fetch request:
- (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];
}
Again, this very same code fetches many objects when using in-memory store, but an empty fetchedObjects array when using SQLite.
I've read Apple's documentation with regard to the special considerations to make when using predicates and sortDescritors with SQLite store. I am using a single (many-)to-many relationship (categories) in the predicate, so this should be fine?
There is no error returned from the fetch. Simply no objects (fetchedResultsController.fetchedObjects is empty).
Any guidance would be greatly appreciated.
Thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我最终弄清楚了这个问题。
我的查询没有返回结果,确实没有结果。追溯到我创建对象并用值填充关系的地方,我注意到我做错了。我尝试这样做:
这并没有真正将 newCategory 添加到类别关系中。
在意识到 Core Data 自动生成一对多关系的访问器后,我使用以下命令添加 newCategory:
这正确地将 newCategory 添加到关系中。
除此之外,我在 Provider.h 中声明了 addCategoriesObject 以抑制编译器警告。这为我解决了这个问题。
唯一需要注意的是,编译器找不到 addCategoriesObject: 的实现,并警告“不完整的实现”。我也没有找到抑制此警告的方法。
I've figured out this issue eventually.
My query returned no results there were indeed no results. Tracing this back to where I was creating the objects and populating the realtionships with values I noticed that I was doing it wrong. I tried to do:
Which did not really add newCategory to the categories relationship.
After having realized that Core Data generates the accessors for to-many relationships automatically, I used the following to add newCategory:
This properly added newCategory to the relationship.
In addition to that I declared addCategoriesObject in Provider.h to suppress the compiler warning. This resolved the issue for me.
The only remaining caveat is that the compiler does not find the implementation of addCategoriesObject: and warns about "incomplete implementation". I haven't figured out a way to suppress this warning too.
我知道 SQLite 存储在某些情况下存在
"ANY"
获取问题(我不记得确切的情况)。也许尝试修改您的搜索谓词以查看是否得到不同的结果,例如I know SQLite stores have problems with
"ANY"
fetches in some cases (I don't remember the exact ones). Maybe try modifying your search predicate to see if you get different results, e.g.