我正在为我的iOS项目使用Core Data,我得到一个“终止应用程序,因为未捕获的异常'NSInvalidArgumentException',原因:'executeFetchRequest:错误:获取请求必须有一个实体。'”运行时出错应用程序。我的应用程序确实有一个实体,但我不确定为什么会出现此错误。
以下是文件中包含错误的核心数据代码:
#pragma mark - Table view data source
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
// Return the number of sections.
return [[self.fetchedResultsController sections] count];
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo numberOfObjects];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"ClassesCell";
ClassTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[ClassTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[self configureCell:cell atIndexPath:indexPath];
return cell;
}
- (void)configureCell:(ClassTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath {
Classes *classID = [self.fetchedResultsController objectAtIndexPath:indexPath];
cell.classLabel.text = classID.classTitle;
cell.periodLabel.text = classID.period;
}
#pragma mark - Fetched results controller
- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"MyClassesID" inManagedObjectContext:self.managedObjectContext];
assert(self.managedObjectContext);
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"period" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObjects:sortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:nil cacheName:@"Master"];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
/*
Replace this implementation with code to handle the error appropriately.
abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
*/
NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
abort();
}
return _fetchedResultsController;
}
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
[self.tableView beginUpdates];
}
- (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type {
switch(type) {
case NSFetchedResultsChangeInsert:
[self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject
atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type
newIndexPath:(NSIndexPath *)newIndexPath {
UITableView *tableView = self.tableView;
switch(type) {
case NSFetchedResultsChangeInsert:
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeDelete:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
case NSFetchedResultsChangeUpdate:
[self configureCell:[tableView cellForRowAtIndexPath:indexPath]
atIndexPath:indexPath];
break;
case NSFetchedResultsChangeMove:
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath]
withRowAnimation:UITableViewRowAnimationFade];
break;
}
}
- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
[self.tableView endUpdates];
}
答案 0 :(得分:0)
您需要确保设置了托管对象上下文引用。如果未设置,则获取请求将无法找到实体。
您必须拥有一个类,它是托管对象上下文的所有者。默认情况下(从Apple提供的模板),这是应用程序委托。当app委托创建控制器类时,它应该向控制器传递对MOC的引用。如果应用程序委托不创建控制器,则控制器可以转到应用程序委托以获取引用。
答案 1 :(得分:0)
<强> FIRST:强> 在创建数据模型时,最好不要使用任何NSObject保留字,例如“Class”。我刚刚在Xcode 4.6.3中尝试使用名称“class”作为属性,Data Modeller告诉我“class”是NSObject中的保留名称。对于自我,实体,描述或其他词语也是如此。
<强> SECOND:强> 此外,可能发生的是您最初创建了数据模型,运行Core Data应用程序来测试它,然后您修改了Core Data Model,现在您尝试再次针对旧的sqlite数据库运行应用程序。要解决此问题,您可以删除模拟器使用的目录中的SQLite数据库,然后再次运行您的应用程序。注意:仅在进行初始开发时才执行此操作,并且从未在发布应用程序后执行此操作。发布应用程序后,请使用Core Data Model Versioning和Data Migration。
<强>说明强>
启动终端控制台。
要找到它首先进入iPhone模拟器目录的位置,如下所示:
cd~ / Library / Application \ Support / iPhone \ Simulator /
然后根据您正在测试的iOS版本(我的6.1版本),更改下面适合您的版本:
cd 6.1 /应用程序
模拟器创建的目录名称看起来很神秘。你可能会是最后一个,或者如果你要回到模拟不同项目之间的第四个,它可能是倒数第二个,最后一个等等。首先尝试最后一个。我的如下:F53A66CD-DB9A-4440-9178-28BCF4A7A571 因此我做了以下事情:
cd F53A66CD-DB9A-4440-9178-28BCF4A7A571
然后输入:
cd Documents
然后输入以下命令列出文件:
<强> LS 强>
您应该会看到列出的.sqlite文件。 说你的是myClasses.sqlite
要删除它,请输入以下内容:
rm myClasses.sqlite
然后构建并运行以再次测试您的应用程序。
Dougpan.com