gpt4 book ai didi

ios - 尝试删除表中的行时出现错误 'Invalid update: invalid number of rows in section 0'

转载 作者:技术小花猫 更新时间:2023-10-29 10:21:24 28 4
gpt4 key购买 nike

我的代码似乎运行良好,但当我滑动以删除 UITableView 中的一行时,应用程序崩溃并显示以下内容:

错误

LittleToDoApp[70390:4116002] *** 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 (1) must be equal to the number of rows contained in that section before the update (1), plus or minus the number of rows inserted or deleted from that section (0 inserted, 1 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'

ViewController.m

#import "ViewController.h"
#import "ToDoItem.h"
#import "ToDoItemSvcCache.h"

@interface ViewController ()

@end

@implementation ViewController

@synthesize tableView;

ToDoItemSvcCache *ToDoItemSvc = nil;

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

ToDoItemSvc = [[ToDoItemSvcCache alloc] init];
}



- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

- (IBAction)deleteToDoItem:(id)sender {
NSLog(@"Deleting ToDoItem");

[self.view endEditing:YES];

}

- (IBAction)addToDoItem:(id)sender {

[self.view endEditing:YES];

NSLog(@"saveToDoItem: entering");
ToDoItem *todoitem = [[ToDoItem alloc] init];
todoitem.todoitem = _toDoItem.text;
[ToDoItemSvc createToDoItem:todoitem];

[self.tableView reloadData];
NSLog(@"saveToDoItem: todoitem saved");

}


- (UITableViewCell *)tableView:(UITableView *)tableView
cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *simpleTableIdentifier = @"toDoItemCell";
UITableViewCell *cell =
[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:simpleTableIdentifier];
}
ToDoItem *toDoItem = [[ToDoItemSvc retrieveAllToDoItems]
objectAtIndex:indexPath.row];
cell.textLabel.text = [toDoItem description];
return cell;
}



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

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}



- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if ([segue.identifier isEqualToString:@"viewToDoItem"]) {
NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];
SecondViewController *destViewController = segue.destinationViewController;
UITableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
destViewController.toDoItemName = cell.textLabel.text;
}
}

#pragma hiding status bar

- (BOOL)prefersStatusBarHidden {
return YES;
}

// here we get back from both styles
- (IBAction)unwindFromDetailViewController:(UIStoryboardSegue *)segue
{
// UIViewController *detailViewController = [segue sourceViewController];
NSLog(@"%@", segue.identifier);
}

//Allows the delete button to show up when left swipping a list item

- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
// Return YES - we will be able to delete all rows
return YES;
}

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
// Will add code to actually delete a row here. Adding NSLog so we know its triggering though
NSLog(@"Deleted row.");

[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

[self.tableView reloadData];

}

@end

ToDoItemSvc.h

#import <Foundation/Foundation.h>
#import "ToDoItem.h"

@protocol ToDoItemSvc <NSObject>

- (ToDoItem *) createToDoItem: (ToDoItem *) todoitem;
- (NSMutableArray *) retrieveAllToDoItems;
- (ToDoItem *) updateToDoItem: (ToDoItem *) todoitem;
- (ToDoItem *) deleteToDoItem: (ToDoItem *) todoitem;

@end

完整来源

https://github.com/martylavender/LittleToDoApp/tree/Storyboards

编辑

在 Fennelouski 发表评论后跟进,我是否应该按照这些思路做些事情?

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

if (editingStyle == UITableViewCellEditingStyleDelete) {
[self.toDoItem removeObjectAtIndex:indexPath.row];

[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
[self.tableView reloadData];

}
}

编辑2

这是我得到的:

https://www.evernote.com/l/AJiah58lVhdGXIYO1F5yv6fJXc7k3WjRLNYB/image.png

最佳答案

表中的行数是 [[ToDoItemSvc retrieveAllToDoItems] count]。当您删除表中的 1 行时,表中的行数应比删除任何行之前的行数少 1。删除 1 行并调用 [self.tableView reloadData] 后,tableView 检查表中有多少行。此时,numberOfRowsInSection 将返回 [[ToDoItemSvc retrieveAllToDoItems] count]。这现在应该比删除行之前少 1

简短的回答是,您需要先从数据源中删除一个项目,它看起来是 [ToDoItemSvc retrieveAllToDoItems],然后删除一行。

对此的赞美是,当您添加一行时,您还需要向数据源添加一个项目。

这些更改需要在您调用 reloadData 之前发生。

编辑

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
// Actually remove the data from the source
[ToDoItemSvc deleteToDoItem:[ToDoItemSvc retrieveAllToDoItems][indexPath.row]]

[self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];

[self.tableView reloadData];
}

ELI5:一位老师有五个学生:Alice、Bob、Charlie、Diane 和 Eric。鲍勃的妈妈在午饭前很早就去学校接他了。午饭后,老师点名了,他 panic ,因为名单上说应该有五个 child ,而他只有四个 child 。鲍勃在哪里?!

如果 Bob 的妈妈在带他离开学校时将他的名字从名单中删除,那么老师就不会 panic 。

关于ios - 尝试删除表中的行时出现错误 'Invalid update: invalid number of rows in section 0',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30516970/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com