Iphone 删除UITableViewController中的记录会引发错误
问题:单击给定表/节行的“删除”按钮时,出现以下错误:**由于未捕获异常而终止应用程序“NSInternalInconsistencyException”,原因:“无效更新:节0中的行数无效。”。更新4之后现有节中包含的行数必须等于更新4之前该节中包含的行数,加上或减去从该节中插入或删除的行数0 inserted,1 deleted。” 从我读到的关于此症状的其他帖子中,我推测我应该手动删除datasource数组中的一个元素,但不确定如何访问此方法中的节数组:Iphone 删除UITableViewController中的记录会引发错误,iphone,objective-c,uitableview,Iphone,Objective C,Uitableview,问题:单击给定表/节行的“删除”按钮时,出现以下错误:**由于未捕获异常而终止应用程序“NSInternalInconsistencyException”,原因:“无效更新:节0中的行数无效。”。更新4之后现有节中包含的行数必须等于更新4之前该节中包含的行数,加上或减去从该节中插入或删除的行数0 inserted,1 deleted。” 从我读到的关于此症状的其他帖子中,我推测我应该手动删除datasource数组中的一个元素,但不确定如何访问此方法中的节数组: // COMMIT EDITIN
// COMMIT EDITING STYLE
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"indexPath: %@", indexPath);
if (editingStyle == UITableViewCellEditingStyleDelete) {
// Delete the row from the data source
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
[tableView endUpdates]; // throws error here
[tableView reloadData];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
我认为这种情况的复杂性是由于plist FormEntries.plist我从中提取的数据在我的应用程序中保存了用户输入的所有内容,因此我必须为每个部分调用并过滤它。这可以很好地填充UITableView及其所有部分,但由于正在为每个部分及其内部创建一个新的筛选数组,因此我不确定如何再次访问它以删除元素,从而更正上述错误消息。下面是我如何加载每个表节的数据:
// CELL FOR ROW AT INDEXPATH
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath (NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
NSNumber *numScreenId = [[arrayOfModulesScreens objectAtIndex: indexPath.section] objectForKey: @"id"];
NSMutableArray *arrayRecords = [epFrameWork selectPlist: @"FormEntries" filterByKey: @"screen_id" keyValue:numScreenId];
NSString *strTitle = [[arrayRecords objectAtIndex: indexPath.row] objectForKey: @"storage_string"];
cell.textLabel.text = strTitle;
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
-不确定这是否有助于诊断问题,但在这里它仍然是如此--
// TITLE FOR HEADER IN SECTION
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
return [[arrayOfModulesScreens objectAtIndex: section] objectForKey: @"screen_title"];
}
// NUMBER OF SECTIONS IN TABLE VIEW
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return [arrayOfModulesScreens count];
}
// NUMBER OF ROWS IN SECTION
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSNumber *numScreenId = [[arrayOfModulesScreens objectAtIndex: section] objectForKey: @"id"];
NSMutableArray *arrayRecords = [epFrameWork selectPlist: @"FormEntries" filterByKey: @"screen_id" keyValue:numScreenId];
int rowCount = [arrayRecords count];
return rowCount;
}
处理这种情况或解决上述错误消息的最佳方法是什么
-更新-
下面是我如何确定要删除的plist记录,假设我需要这样做来解决原始错误:
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
int g = indexPath.row;
int count = -1;
UITableViewCell *tvc = [[UITableViewCell alloc] init];
for(id element in tableView.subviews) {
if([element isKindOfClass:[UITableViewCell class]]) {
count +=1;
NSLog(@"g: %d - count: %d", g , count);
if(count == g) {
tvc = element;
NSLog(@"tvc: %@ - UID: %@ - g: %d - count: %d", tvc, tvc.detailTextLabel.text, g , count);
}
}
}
我的逻辑是在CellForRowatineXpath方法中的tvc.detailTextLabel.text上设置一个隐藏的唯一标识符,这将通过调用[array removeObjectAtIndex:uid]让我知道要过滤和删除plist中的哪个记录,其中array是我过滤的plist数组。现在唯一的问题是NSLog中的tvc总是返回索引0处的记录,而不是保存我单击的delete按钮的行
NSLog返回:tvc:这只是一团混乱,还是有更干净的解决方案?但是ya,仍然被难住了。这个错误肯定与您错误处理试图加载到表中的数据有关。我发现处理修改表内容的最简单和最安全的方法是按照这些思路做一些事情,并在tableView中进行必要的调整:CommittedItingStyle:
//REMOVE A CELL FROM A SECTION
[yourTable beginUpdates];
[yourTable deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationBottom];
[yourTable endUpdates];
[yourTable reloadData];
此外,您还需要确保数组已正确更新,以便将更改反映在表中。这就是我最终解决问题的方法: 我改变了这一切:
int g = indexPath.row;
int count = -1;
UITableViewCell *tvc = [[UITableViewCell alloc] init];
for(id element in tableView.subviews) {
if([element isKindOfClass:[UITableViewCell class]]) {
count +=1;
NSLog(@"g: %d - count: %d", g , count);
if(count == g) {
tvc = element;
NSLog(@"tvc: %@ - UID: %@ - g: %d - count: %d", tvc, tvc.detailTextLabel.text, g , count);
}
}
}
一句简单的话:
UITableViewCell *cell = [[self tableView] cellForRowAtIndexPath:indexPath];
这使我能够识别我正在使用的手机。因此,我的最终代码如下所示:
// COMMIT EDITING STYLE
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
UITableViewCell *cell = [[self tableView] cellForRowAtIndexPath:indexPath];
[epFrameWork deleteRecordFromPlist:@"FormEntries" uid:cell.detailTextLabel.text];
[tableView reloadData];
}
else if (editingStyle == UITableViewCellEditingStyleInsert) {
// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
}
}
-(void) deleteRecordFromPlist:(NSString *)plist uid:(NSString *)uId {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *tmpFileName = [[NSString alloc] initWithFormat:@"%@.plist", plist];
NSString *path = [documentsDirectory stringByAppendingPathComponent:tmpFileName];
NSMutableArray *array = [[NSMutableArray alloc] initWithContentsOfFile:path];
NSDictionary *dict = [[NSDictionary alloc] init];
NSString *tmpUid;
for(int i=0; i < [array count]; i++) {
dict = [array objectAtIndex:i];
tmpUid = [dict valueForKey:@"uid"];
if([tmpUid isEqualToString:uId]) {
[array removeObjectAtIndex:i];
[array writeToFile:path atomically:YES];
}
}
}
刚刚做了你推荐的更新。抛出相同的错误,但在此行[tableView endUpdates];。我已经更新了我的原始帖子以反映这一更新。NSLog@indexPath:%@,indexath;CommittedItingStyle方法中的第一条语句生成:indexPath:2个索引[0,3]。甚至不知道那是什么意思。3告诉我们1行被删除了,因为1比错误中提到的4少?表行和表示该行的数组元素之间有什么区别?我想它们是两种不同的东西。抱歉,我对这一切还是很陌生。只要阅读nsindepath类ref,现在这一部分就更有意义了。现在我只需要找出如何解决原始错误。是的。我已经构建了一个相当笨重的工作环境,但仍然试图找出为什么这个工作不起作用的原因。有没有一个简单的解决方案,或者我应该把我的工作作为另一个答案发布?或者我应该在评论部分发布我的解决方案代码?我只是发布了我的解决方案代码作为对原始代码的更新。