ios 核心数据示例,无效更新:第 0 节中的行数无效
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5043729/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Core Data example, Invalid update: invalid number of rows in section 0
提问by Keith Boruta
I am novice at iOS and XCode, and am working through a Core Data tutorial and am really stumped. I continually get the error in the error logs of the following:
我是 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
)
Here is my addReservation code:
这是我的 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];
}
I believe that my resArray is not getting the data from the method that I input in programatically, but I am not sure, and I am not sure how to fix it.
我相信我的 resArray 没有从我以编程方式输入的方法中获取数据,但我不确定,我不确定如何修复它。
Any help is appreciated.
任何帮助表示赞赏。
回答by Kris Babic
I would take a look at your implementation of
我想看看你的实现
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
The error you specified occurs when the value returned from numberOfRowsInSection does not equal the previous value plus the number of rows you added using insertRowsAtIndexPaths. If your implementation of numberOfRowsInSection is using [myArray count], then make sure that the array instance used is the same one into which you are adding the reservation entry. If you have not implemented this method, then that would be your problem. Here is an example of how that method should look:
当 numberOfRowsInSection 返回的值不等于前一个值加上您使用 insertRowsAtIndexPaths 添加的行数时,就会发生您指定的错误。如果您对 numberOfRowsInSection 的实现使用了 [myArray count],那么请确保所使用的数组实例与您添加预留条目的数组实例相同。如果你还没有实现这个方法,那将是你的问题。这是该方法的外观示例:
- (NSInteger)tableView:(UITableView *)tableView
numberOfRowsInSection:(NSInteger)section {
return [resArray count];
}
As a backup, you can add log statements that list the size of the array before and after the addition, and inside of the numberOfRowsInSection function.
作为备份,您可以在 numberOfRowsInSection 函数内部添加列出添加前后数组大小的日志语句。
回答by Peter Kelly
The order that you delete/insert from the tableView and you delete/insert from the underlying datasource can be important. Apple documentation has updating the view first and then the datasource. However, deleting/inserting from the view internally calls - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
which, if you're like me, returns the count
of the underlying datasource. Because this has not changed, the runtime will complain and crash. So remove from your datasource first, then the view.
从 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];
}
回答by Charlie
To me it looks as if you are inserting the object before you accually make the changes to it. I could be wrong as i am also a novice!
对我来说,它看起来好像是在对对象进行更改之前插入对象。我可能是错的,因为我也是新手!
回答by Graham Gardiner
- (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];
}
}
This works when deleting and adding records to a core data table with fetchedResultsController.
这在使用 fetchedResultsController 删除和添加记录到核心数据表时有效。