带有核心数据 insertRowsAtIndexPaths 的 UITableView 导致 NSInternalInconsistencyException

Posted

技术标签:

【中文标题】带有核心数据 insertRowsAtIndexPaths 的 UITableView 导致 NSInternalInconsistencyException【英文标题】:UITableView with Core Data insertRowsAtIndexPaths causes NSInternalInconsistencyException 【发布时间】:2011-01-12 21:57:29 【问题描述】:

我目前正在为 iPhone 编写一个简单的表格视图示例,但对于我来说,我无法弄清楚为什么会发生以下异常。

工作流程如下: 我有一个 UIViewController,我正在向其中添加一个 UIView。然后我向那个视图添加一个以编程方式定义的 UITableView

- (id)init
    [super initWithNibName:nil bundle:nil];

    tableView = [[UITableView alloc] initWithFrame:CGRectMake(20, 180, 280, 180) style:UITableViewStyleGrouped];
    tableView.backgroundColor = [UIColor redColor];
    tableView.delegate = self;

    return self;

一旦完成,我将使用 UITableViewDelegate 并覆盖以下方法,这应该会导致我的表被编辑。这是由按钮和

的选择器方法触发的
- (void)editList:(id)sender
    [self setEditing:YES animated:YES];
    [editButton addTarget:self action:@selector(doneList:) forControlEvents:UIControlEventTouchUpInside];
    [editButton setBackgroundImage:[UIImage imageNamed:@"ApplyChanges.png"] forState:UIControlStateNormal];

还有另一种称为 doneList 的方法,它在完成时被触发,但代码并没有那么远。因此,一旦单击按钮,就会调用我的 setEditing 委托并引发错误。

这是委托方法

- (void)setEditing:(BOOL)flag animated:(BOOL)animated 
    NSLog(@"setEditing");
    // Always call super implementation of this method, it needs to do some work
    [super setEditing:flag animated:animated];
    // We need to insert/remove a new row in to table view to say "Add New Item..."
    if (flag) 
        // If entering edit mode, we add another row to our table view
        int count = entries.count;
        NSLog(@"int: %i", count);
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:count inSection:0];
        [tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];    
     else 
        // If leaving edit mode, we remove last row from table view
        NSIndexPath *indexPath = [NSIndexPath indexPathForRow:[entries count] inSection:0];
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationRight];
    

关于这段代码在执行期间的几件事: 1)最初“条目”数组为空,因此计数为 0,这似乎返回了一个不为空的 indexPath 对象 2)当条目中填充了虚假数据时,计数会正确增加,但仍然会发生错误 3) 我已经尝试删除 super setEditing 调用,但仍然出现错误

最后是错误。

2011-01-12 16:46:13.623 Book[6256:40b] numberOfRowsInSection
2011-01-12 16:46:13.625 Book[6256:40b] numberOfRowsInSection
2011-01-12 16:46:17.658 Book[6256:40b] setEditing
2011-01-12 16:46:17.659 Book[6256:40b] int: 0
2011-01-12 16:46:17.660 Book[6256:40b] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1447.6.4/UITableView.m:976
2011-01-12 16:46:17.692 Book[6256:40b] *** 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).'

如果有明显的遗漏,请告诉我,是否可能需要包含另一个我不知道的委托方法?

【问题讨论】:

如果您在行数组中从零开始,您确定要 entry.count 吗? 【参考方案1】:

好的,伙计们。看来,当使用设置 UITableViewDelegate 的自定义 UIViewController 时,您还需要设置 UITableViewDataSource 并将 tableViews 数据源指向 self。

示例代码。

旧代码

// Header File 

@interface MyViewController : UIViewController <UITableViewDelegate> 



// Main File

- (id)init
    [super initWithNibName:nil bundle:nil];

    tableView = [[UITableView alloc] initWithFrame:CGRectMake(20, 180, 280, 180) style:UITableViewStyleGrouped];
    tableView.backgroundColor = [UIColor redColor];
    tableView.delegate = self;

    return self;

更新的工作代码

// Header File 

@interface MyViewController : UIViewController <UITableViewDelegate, UITableViewDataSource> 



// Main File

- (id)init
    [super initWithNibName:nil bundle:nil];

    tableView = [[UITableView alloc] initWithFrame:CGRectMake(20, 180, 280, 180) style:UITableViewStyleGrouped];
    tableView.backgroundColor = [UIColor redColor];
    tableView.delegate = self;
    tableView.dataSource = self;

    return self;

【讨论】:

以上是关于带有核心数据 insertRowsAtIndexPaths 的 UITableView 导致 NSInternalInconsistencyException的主要内容,如果未能解决你的问题,请参考以下文章

带有核心数据的 NSPredicate,在字符串属性中搜索带有边界的单词

从核心数据中删除/添加到核心数据后,带有列表的 SwiftUI TabView 不刷新

带有核心数据删除错误的 NSFetchedResultsController

带有核心数据的慢速 UISearchDisplayController

带有 A-Z 部分的核心数据

带有谓词的 ios 核心数据错误