【问题标题】:Core Data example, Invalid update: invalid number of rows in section 0核心数据示例,无效更新:第 0 节中的行数无效
【发布时间】:2011-06-29 22:43:46
【问题描述】:

我是 iOS 和 XCode 的新手,正在学习 Core Data 教程,我真的很难过。我不断收到以下错误日志中的错误:

Exception Type:  EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Crashed Thread:  0  Dispatch queue: com.apple.main-thread

Application Specific Information:
iPhone Simulator 235, iPhone OS 4.2 (iPad/8C134)
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0.  The number of rows contained in an existing section after the update (0) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (1 inserted, 0 deleted).'
*** Call stack at first throw:
(
        0   CoreFoundation                      0x010a6be9 __exceptionPreprocess + 185
        1   libobjc.A.dylib                     0x00e9b5c2 objc_exception_throw + 47
        2   CoreFoundation                      0x0105f628 +[NSException raise:format:arguments:] + 136
        3   Foundation                          0x000b447b -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
        4   UIKit                               0x00336a0f -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] + 8424
        5   UIKit                               0x00325f81 -[UITableView insertRowsAtIndexPaths:withRowAnimation:] + 56
        6   SimpleRes                           0x00002496 -[RootViewController addReservation] + 465
        7   UIKit                               0x002b9a6e -[UIApplication sendAction:to:from:forEvent:] + 119
        8   UIKit                               0x004c7167 -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 156
        9   UIKit                               0x002b9a6e -[UIApplication sendAction:to:from:forEvent:] + 119
        10  UIKit                               0x003481b5 -[UIControl sendAction:to:forEvent:] + 67
        11  UIKit                               0x0034a647 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
        12  UIKit                               0x003491f4 -[UIControl touchesEnded:withEvent:] + 458
        13  UIKit                               0x002de0d1 -[UIWindow _sendTouchesForEvent:] + 567
        14  UIKit                               0x002bf37a -[UIApplication sendEvent:] + 447
        15  UIKit                               0x002c4732 _UIApplicationHandleEvent + 7576
        16  GraphicsServices                    0x018bda36 PurpleEventCallback + 1550
        17  CoreFoundation                      0x01088064 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
        18  CoreFoundation                      0x00fe86f7 __CFRunLoopDoSource1 + 215
        19  CoreFoundation                      0x00fe5983 __CFRunLoopRun + 979
        20  CoreFoundation                      0x00fe5240 CFRunLoopRunSpecific + 208
        21  CoreFoundation                      0x00fe5161 CFRunLoopRunInMode + 97
        22  GraphicsServices                    0x018bc268 GSEventRunModal + 217
        23  GraphicsServices                    0x018bc32d GSEventRun + 115
        24  UIKit                               0x002c842e UIApplicationMain + 1160
        25  SimpleRes                           0x00001ab0 main + 102
        26  SimpleRes                           0x00001a41 start + 53
)

这是我的 addReservation 代码:

-(void)addReservation{

    // Create and configure a new instance of the Event entity.
    Reservations *reservation = (Reservations *)[NSEntityDescription insertNewObjectForEntityForName:@"Reservations" inManagedObjectContext:managedObjectContext];

    [reservation setEnd_Time: [[NSDate alloc]init]];
    [reservation setReservation_Date:[[NSDate alloc]init]];
    [reservation setStart_Time:[NSDate date]];
    [reservation setParty_Size: [NSNumber numberWithInt:4]];
    [reservation setPhone_Number: [NSNumber numberWithInt: 1234567890]];
    [reservation setName: @"Keith"];
    [reservation setNotes: @"He's really hot!"];
    [reservation setPerson_Responsible: @"Lisa"];
    [reservation setTables_Excluded: @"3,5,8"];

    NSError *error = nil;
    if (![managedObjectContext save:&error]) {
        }

    [resArray insertObject:reservation atIndex:0];
    NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
    [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                          withRowAnimation:UITableViewRowAnimationFade];
    [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:YES];
}

我相信我的 resArray 没有从我以编程方式输入的方法中获取数据,但我不确定,也不知道如何修复它。

感谢任何帮助。

【问题讨论】:

  • 如果你按照Apple iOS Core Data教程,模板生成的文件有return 0;对于 numberOfSectionsInTable 委托方法。只需将该行更改为返回 1 就可以了。

标签: ipad ios core-data


【解决方案1】:

我会看看你的实现

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

当从 numberOfRowsInSection 返回的值不等于前一个值加上您使用 insertRowsAtIndexPaths 添加的行数时,就会出现您指定的错误。如果您的 numberOfRowsInSection 实现使用 [myArray count],请确保使用的数组实例与您要添加预留条目的数组实例相同。如果您还没有实现此方法,那将是您的问题。以下是该方法的外观示例:

- (NSInteger)tableView:(UITableView *)tableView 
 numberOfRowsInSection:(NSInteger)section {
    return [resArray count];
}

作为备份,您可以在 numberOfRowsInSection 函数内部添加列出数组大小的日志语句。

【讨论】:

  • 如果你像我一样笨,数组可能为空。 :)
【解决方案2】:

从 tableView 中删除/插入以及从底层数据源中删除/插入的顺序可能很重要。 Apple 文档首先更新视图,然后更新数据源。但是,从视图中删除/插入会在内部调用 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section,如果您像我一样,它会返回底层数据源的 count。因为这没有改变,运行时会抱怨和崩溃。所以首先从你的数据源中删除,然后是视图。

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    // Return the number of rows in the section.
    return [recentImages count];
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {

    // Delete from underlying data source first!
    recentImages = [recentImages removeObjectAtIndex:indexPath.row];

    // Then perform the action on the tableView
    if (editingStyle == UITableViewCellEditingStyleDelete)
    {   
        [tableView beginUpdates];
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
                             withRowAnimation:UITableViewRowAnimationFade];        
        [tableView endUpdates];
    }

    // Finally, reload data in view
    [self.tableView reloadData];
}

【讨论】:

  • 最后对reloadData 的调用是多余的。您应该使用begin/endUpdates 将表同步到您的基础数据 reloadData 以重新加载所有内容(这在 CPU 方面成本更高,并且可能看起来不太好用户)。但没有必要两者都做。我已提交修改。
【解决方案3】:

在我看来,您似乎是在实际更改对象之前插入对象。我可能是错的,因为我也是新手!

【讨论】:

    【解决方案4】:
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    
    
            return [[[self.fetchedResultsController sections] objectAtIndex:section] numberOfObjects];
    
    
    
       }
    
    - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
    
        if (editingStyle == UITableViewCellEditingStyleDelete) {
    
            [self.tableView beginUpdates]; 
    
            // Delete the object that was swiped
            YourTableName *objectToDelete = [self.fetchedResultsController objectAtIndexPath:indexPath];
            NSLog(@"Deleting (%@)", objectToDelete.fieldname);
            [self.managedObjectContext deleteObject: objectToDelete];
            [self.managedObjectContext save:nil];
    
            // Delete the (now empty) row on the table
            [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
    
    
    
            [self.tableView reloadData];
    
            [self.tableView endUpdates];
    
    
              }
    }
    

    这在使用 fetchedResultsController 删除和添加记录到核心数据表时有效。

    【讨论】:

      猜你喜欢
      • 2014-10-28
      • 1970-01-01
      • 1970-01-01
      • 2013-07-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-12
      相关资源
      最近更新 更多