2013-08-04 46 views
0

我正在为我的iOS项目使用核心数据,并且由于未捕获的异常'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

有'managedObjectContext'被设置或者是'nil'运行的代码是什么时候? – Wain

+0

@我不确定。这是我第一次在iOS上编码。我能在哪里找到答案? – Mayankmmmx

+0

在创建提取请求的行上放置断点并进行调试以检查是否设置了引用。 – Wain

回答

0

你需要确保被管理对象上下文引用设置。如果未设置,则获取请求将无法找到实体。


您必须有一个类,它是托管对象上下文的所有者。默认情况下(来自Apple提供的模板),这是应用程序委托。当应用程序委托创建控制器类时,它应该向控制器传递对MOC的引用。如果应用程序委托不创建控制器,则控制器可以转到应用程序委托以获取参考。

+0

如何设置引用? – Mayankmmmx

+0

我有为获取请求生成的相同的异常,我检查了我的MOC不是零。我该怎么办? – AceN

0

FIRST: 当您创建数据模型时,避免使用任何NSObject保留字如“Class”是一个好习惯。我刚刚在Xcode 4.6.3中使用名称“class”作为属性,Data Modeller告诉我“class”是NSObject中的保留名称。对于像自我,实体,描述或其他词语一样。

第二: 此外,什么可能发生的是,最初创建数据模型,跑到你的核心数据的应用程序进行测试,然后你修改了核心数据模型,现在你正试图再次运行应用程序针对旧的sqlite数据库。要解决这个问题,您可以删除模拟器使用的目录中的SQLite数据库,然后再次运行您的应用程序。注意:只有在您正在进行初始开发时才会执行此操作,并且从未在您发布应用程序之后进行此操作在您的应用发布后,使用核心数据模型版本控制和数据迁移。

说明:

启动终端控制台

要找到它首先获取到iPhone模拟器目录,如下所示:

CD〜/库/应用程序的\ Support/iPhone \模拟器/

然后根据其IOS版本你

CD 6.1 /应用

目录南:下面适合你的测试(我的是6.1)改线模拟器创建的模型是神秘的。你可能是最后一个,或者如果你在模拟不同的项目之间回到第四个,它可能是倒数第二,倒数第三等。首先尝试最后一个。我的是以下几点:F53A66CD-DB9A-4440-9178-28BCF4A7A571 所以我做了以下内容:

CD F53A66CD-DB9A-4440-9178-28BCF4A7A571

然后输入:

CD文件

然后输入以下命令列出文件:

ls

您应该看到列出的.sqlite文件。 说你是myClasses.sqlite

要删除键入以下内容:

RM myClasses.sqlite

然后建立并运行再次测试您的应用程序。

Dougpan.com

+0

我试过了,文件名为HomeworkApp.sqlite,我将其删除。再次运行应用程序后,同样的错误仍然存​​在 – Mayankmmmx

+0

您是否尝试使用核心数据模型版本控制和数据迁移?哈希用于比较数据模型的任何修改与代码中的内容。另外请记住,如果当你选择了一个属性并且你选择了编辑,创建NSManagedObject子类时,你的代码可能会使用一个类。您可能还需要更新它,然后查看并更新您的代码,以便使用这些类。 – dougscode

+0

试着放一些调试代码来测试你的获取请求,例如:NSArray * fetch = [itemController.managedObjectContext executeFetchRequest:fetchRequest error:&error]; NSLog(@“%d”,fetch.count); – dougscode