断言失败 - [UITableView _endCellAnimationsWithContext:]

时间:2012-04-13 03:27:13

标签: objective-c ios uitableview crash

希望这将是一个快速解决方案。我一直试图弄清楚我一直在犯的错误。下面列出了错误,并且appdelagate低于该值。

感谢任何帮助。

由于

  

2012-04-12 21:11:52.669 Chanda [75100:f803] --- -[UITableView _endCellAnimationsWithContext:]中的断言失败,/SourceCache/UIKit_Sim/UIKit-1914.84/UITableView.m:1037   2012-04-12 21:11:52.671 Chanda [75100:f803] ---因未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:'无效更新:第0部分中的行数无效。更新后的现有部分中包含的行(2)必须等于更新前的该部分中包含的行数(2),加上或减去从该部分插入或删除的行数(插入1个,删除0个)加上或减去移入或移出该部分的行数(0移入,0移出)。'

#import "AppDelegate.h"

@implementation AppDelegate

@synthesize window = _window;
@synthesize databaseName,databasePath; 

- (BOOL)application: (UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions {
    self.databaseName = @"Customers.db";

    NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentDir = [documentPaths objectAtIndex:0];
    self.databasePath = [documentDir stringByAppendingPathComponent:self.databaseName];
    [self createAndCheckDatabase];

    return YES;
}

- (void)createAndCheckDatabase {
    BOOL success;

    NSFileManager *fileManager = [NSFileManager defaultManager];
    success = [fileManager fileExistsAtPath:databasePath];

    if (success) return; 

    NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:self.databaseName];

    [fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}

@end

12 个答案:

答案 0 :(得分:43)

我没有看到您向我们展示这部分代码的原因。您的错误必须连接到我假设的代码中的此部分

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath;

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

可能你在其中一种数据源方法中犯了错误。目前我不可能说出究竟是什么问题,但我认为它可能是这样的:您在numberOfRowsInSection中告诉表格视图,您希望 n 行保留并设置并且在然后cellForRowAtIndexPath只能处理 n - 1 行。

很抱歉,这个答案不能像应有的那样精确。如果您向我们展示您的数据源实现,那么就可以更容易地判断出发生了什么。

答案 1 :(得分:26)

像孙子said最好不战而胜。在我的情况下,每当我看到这种错误消息(即行添加删除之间的差异等)..我甚至没有调试任何东西..我只是避免在我重新加载行等的额外调用..这是99%的发生此错误的情况。

这是发生此错误的常见情况:我有一个UINavigationController并且它有一个UITableView,当我点击一行时它会推送一个新的UITableView,依此类推。当我弹出最后一个UITableview然后返回到UITableView之前,这个错误总是发生在我身上,此时我对基本插入行的loadIt函数进行了不必要的调用并重新加载UITableView

发生这种情况的原因是因为我错误地将我的loadIt函数放在viewDidAppear:animated而不是viewDidLoad中。每次显示viewDidAppear:animated时都会调用UITableViewviewDidLoad只会被调用一次。

答案 2 :(得分:24)

删除行时,请记住它还会在更新时检查部分:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView

如果要删除作为节中最后一项的行,则需要删除整个节(否则可能会导致节数错误并抛出此异常)。

答案 3 :(得分:6)

不要忘记更新确定numberOfRowsInSection的数组。它需要在动画和删除之前进行更新

我们检查部分中的行数是否为1,因为我们必须删除整个部分。

如果有人能让这个答案更清楚,请纠正我。

[self.tableView beginUpdates];
if ([tableView numberOfRowsInSection:indexPath.section] == 1) {

   [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:UITableViewRowAnimationFade];
} else {

   [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
}
[self.tableView endUpdates];

答案 4 :(得分:4)

我将每个section元素放在单独的数组中。然后将它们放入另一个数组(arrayWithArray)。我在这里解决这个问题:

[quarantineMessages removeObject : message];
[_tableView beginUpdates];
if([[arrayWithArray objectAtIndex: indPath.section] count]  > 1)
{
    [_tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indPath] withRowAnimation:UITableViewRowAnimationBottom];
}
else
{
    [_tableView deleteSections:[NSIndexSet indexSetWithIndex:indPath.section]
              withRowAnimation:UITableViewRowAnimationFade];
}
[_tableView endUpdates];

答案 5 :(得分:2)

我遇到了同样的错误。

我使用以下几行

UINib *myCustomCellNib = [UINib nibWithNibName:@"CustomNib" bundle:nil];
[tableView registerNib:myCustomCellNib forCellReuseIdentifier:@"CustomNib"];

在viewDidLoad方法中注册nib,因为我有一个不同的nib也与同一个类相关联。因此,行

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"GBFBLoadingCell"];
除非我在viewDidLoad中注册了nib,否则

返回nil。

我的问题是我忘了在属性检查器中为我的文件“CustomNib.xib”和“CustomNib~iphone.xib”设置标识符。 (或者更确切地说,我忘了在XCode中的属性检查器中键入标识符后按Enter键,以便新名称无法保存。)

希望这有帮助。

答案 6 :(得分:2)

我有同样的错误,在尝试[tableView reloadData]时工作正常。 错误实际上在行

[TabView insertRowsAtIndexPaths:indexPathsArray withRowAnimation:UITableViewRowAnimationRight];

当我尝试检查indexPath值时,它们根据需要不正确。

我通过更改indexPathsArray中的值来修复它。

希望这有帮助。

答案 7 :(得分:1)

它可能是int v; //integer to be read int sign; //sign printf("Enter an integer to compute its sign.\n"); scanf_s("%d", &v); __asm { mov eax, v // load x into A cmp eax, 0 // compare A with value 0 je equal0 // if comparison was == 0 then jmp to equal0 jge greater0 // if comparison was >= 0 then jmp to greater0 mov eax, -1 // set eax to -1 mov sign, eax // sign = -1 jmp done equal0: mov eax, 0 // set eax to 0 mov sign, eax // sign = 0 jmp done greater0: mov eax, 1; // set eax to 1 mov sign, eax // sign = 1 done: } printf("signe of %d is %d.\n", v, sign ); 协议方法之一

对于

UITableViewDataSource

它应该返回一个等于

的总和或结果的整数

- tableView:numberOfRowsInSection: 和/或-insertRowsAtIndexPaths:withRowAnimation:

有关

-deleteRowsAtIndexPaths:withRowAnimation

它应该返回一个等于

的总和或结果的整数

- numberOfSectionsInTableView: 和/或 -insertRowsAtIndexPaths:withRowAnimation:

答案 8 :(得分:1)

如果您正在使用像我这样的NSFetchedResultsController并在后台线程中更新数据,请不要忘记在委托中开始和结束更新:

- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView beginUpdates];
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller {
    [self.tableView endUpdates];
}

答案 9 :(得分:0)

我在核心数据库中遇到了同样的问题。如果你使用了很多FRC,你只需要在numberOfSectionsInTableView中的每个条件内重新加载tableview。

答案 10 :(得分:0)

我在使用Swift和FRC支持的数据存储来管理信息时发生了这种情况。在删除操作中添加一个简单的检查以评估当前的indexPath.section允许我避免无关的调用。我想我明白为什么会出现这个问题......基本上我每当我的数据集为空时都会在顶行中加载一条消息。由于有一个虚假的行,这会产生一个问题。

我的解决方案

... delete my entity, save the datastore and call reloadData on tableView
//next I add this simple check to avoid calling deleteRows when the system (wrongly) determines that there is no section.

       if indexPath.section > 0 {

        tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .None)

            }

答案 11 :(得分:0)

只需检查您调用[yourTableView reloadData];修改值数组后。