代码之家  ›  专栏  ›  技术社区  ›  Daniel Wood

核心数据/未保存结果控制器错误

  •  5
  • Daniel Wood  · 技术社区  · 15 年前

    我在控制核心数据/未保存结果方面遇到了一些问题。我不完全确定错误在哪里,因为消息很模糊。

    当提取的结果控制器未提取任何对象时,插入多个对象时出现问题。如果尝试插入多个尚未提取的对象,则以下代码将崩溃,并出现以下错误。如果我使用它插入一个对象,它不会崩溃;如果已经提取了对象,它也不会崩溃。

    崩溃发生在save:方法上。NSarray中的标题,在本例中,它包含5个字符串。

    严重的应用程序错误。例外 在核心数据更改期间捕获 处理: *[NSCFFART阵列] ObjectAtindex::超出索引(4) 带用户信息的边界(1)(空) * 由于未捕获的异常“nsrangeexception”,正在终止应用程序,原因: '***-[nscfaray对象索引:] 索引(4)超出界限(1)'

    NSEnumerator *titleEnumerator = [titles objectEnumerator];
    NSString *title;
    NSMutableArray *tasks = [NSMutableArray array];
    Todo *todo;
    
    while(title = [titleEnumerator nextObject])
    {
        todo = (Todo *)[NSEntityDescription insertNewObjectForEntityForName:@"Todo" inManagedObjectContext:managedObjectContext];
        todo.title = title;
        todo.state = [NSNumber numberWithInteger:TodoStateIncomplete];
        todo.priority = [NSNumber numberWithInteger:TodoPriorityNormal];
        todo.timeStamp = [NSDate date];
        todo.dueDate = [NSDate distantFuture];
    }
    
    NSError *error;
    
    if(![managedObjectContext save:&error])
    {
        NSLog(@"Unresolved error %@ %@", error, [error userInfo]);
        abort();
    }
    
    4 回复  |  直到 8 年前
        1
  •  5
  •   Community dbr    7 年前

    以下是Marcus Zarra(核心数据书作者)的建议:

    Core Data error when deleting row in tableView

    “尝试在objc_exception_throw上中断,看看是什么方法引发了异常。这应该有助于找到它。”

        2
  •  4
  •   Marcus S. Zarra    15 年前

    在使用iPhone SDK时,核心数据保存中的类似错误通常指向nsfetchedresultsController委托方法中的错误。具体来说,来自苹果的一段示例代码是不正确的,并且经常产生这种错误。我建议查看您的委托方法,并将它们与最新的示例代码进行比较,因为您可能会发现Apple已经更新了文档中的示例代码,如果您重新复制了它们的代码,则此错误可能会消失。

    希望有帮助。

        3
  •  0
  •   T .    15 年前

    我知道这不太可能是答案,但由于车祸发生在save上:我确实记得有一次在这方面有一个奇怪的错误…我犯的错误是这样纠正的,我认为值得一试。

    所以说,试着改变

    NSError *error;
    

    NSError *error = nil;
    
        4
  •  0
  •   Illya Krit    8 年前

    在我的例子中,这个实现是有帮助的(谢谢皮特):

    - (void)controllerWillChangeContent:(NSFetchedResultsController *)controller{ [self.tableView beginUpdates];  }
    
    - (void)controllerDidChangeContent:(NSFetchedResultsController *)controller{
        [self.tableView endUpdates];}
    
    - (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath{
    switch (type) {
        case NSFetchedResultsChangeInsert:
    
            [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            break;
    
        case NSFetchedResultsChangeDelete:
            [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
            break;
    
        case NSFetchedResultsChangeUpdate: {
    
            NSString *sectionKeyPath = [controller sectionNameKeyPath];
            if (sectionKeyPath == nil){
                 break;
            }
    
            [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone];
    
            break;
        }
        case NSFetchedResultsChangeMove: {
    
            if (newIndexPath != nil) {
    
                NSUInteger tableSectionCount = [self.tableView numberOfSections];
                NSUInteger frcSectionCount = [[controller sections] count];
                if (frcSectionCount > tableSectionCount)
                    [self.tableView insertSections:[NSIndexSet indexSetWithIndex:[newIndexPath section]] withRowAnimation:UITableViewRowAnimationNone];
                else if (frcSectionCount < tableSectionCount && tableSectionCount > 1)
                    [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:[indexPath section]] withRowAnimation:UITableViewRowAnimationNone];
    
    
                [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                [self.tableView insertRowsAtIndexPaths: [NSArray arrayWithObject:newIndexPath]
                                      withRowAnimation: UITableViewRowAnimationRight];
    
            }
            else {
                [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:[indexPath section]] withRowAnimation:UITableViewRowAnimationFade];
            }
            break;
        }
    }}
    - (void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type{
    switch (type) {
        case NSFetchedResultsChangeInsert:
            if (!((sectionIndex == 0) && ([self.tableView numberOfSections] == 1)))
                [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
        case NSFetchedResultsChangeDelete:
            if (!((sectionIndex == 0) && ([self.tableView numberOfSections] == 1) ))
                [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
    
            break;
        case NSFetchedResultsChangeUpdate:
            break;
        case NSFetchedResultsChangeMove:
            break;
    }}