【问题标题】:Assertion failure in -[UITableView _endCellAnimationsWithContext:]-[UITableView _endCellAnimationsWithContext:] 中的断言失败
【发布时间】:2012-04-25 11:08:17
【问题描述】:

希望这将是一个快速修复。我一直在试图找出我不断遇到的错误。错误在下面列出,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

【问题讨论】:

  • 您应该将该代码移动到类中,并可能在后台线程中执行它。无论如何,当您尝试删除行而不实际减少表视图的数据源提供的行数时,通常会出现此错误。当您删除行时,您实际上是在删除数据吗?如果你不删除任何行,你能提供你的表格视图数据源实现吗?

标签: objective-c ios uitableview crash


【解决方案1】:

我看不出您向我们展示这部分代码的原因。您的错误必须与我假设的代码中的这一部分有关

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

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

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

很抱歉,这个答案可能不够准确。如果您向我们展示您的数据源实现,那么您会更容易知道发生了什么。

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 谢谢,说得好。您的第一段让我走上了解决类似问题的正确轨道。
    • 这是我的荣幸@scrrr :)
    • 这改变了我看待它的方式——它通过使问题变得无关紧要来解决问题。你摇滚!
    • 感谢 viewDidAppear 而不是 viewDidLoad。这正是我的问题,我已经处理了好几个星期。
    • 我把你的孙子语录打印出来并贴在我的屏幕顶部。感谢您的报价并帮助我找到大量冗余代码:)
    【解决方案3】:

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

    - (NSInteger)numberOfSectionsInTableView:(UITableView *)theTableView
    

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

    【讨论】:

    • 这是纯金!钉子砸在了头上!正是我的问题。
    【解决方案4】:

    不要忘记更新决定 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];
    

    【讨论】:

      【解决方案5】:

      我将每个部分元素放在单独的数组中。然后将它们放入另一个数组(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];
      

      【讨论】:

      • 对我来说,解决问题的是开始和结束更新,谢谢!
      • 我不知道该部分会变空并且需要对其进行动画处理...该死!谢谢!
      • 在这个答案的帮助下,我的代码可以正常工作。贴在下面。
      【解决方案6】:

      我有同样的错误。

      我正在使用以下几行

      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 键,导致新名称无法保存。)

      希望这会有所帮助。

      【讨论】:

      • 我认为您的回答与问题无关。
      【解决方案7】:

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

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

      【讨论】:

        【解决方案8】:

        我遇到了同样的错误,在尝试使用 [tableView reloadData] 时工作正常。 错误实际上是在行

        [TabView insertRowsAtIndexPaths:indexPathsArray withRowAnimation:UITableViewRowAnimationRight];
        

        当我尝试检查 indexPath 值时,它们不符合要求。

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

        希望这会有所帮助。

        【讨论】:

          【解决方案9】:

          它可能是UITableViewDataSource 协议方法之一

          对于

          - tableView:numberOfRowsInSection:
          

          它应该返回一个等于和或结果的整数

          -insertRowsAtIndexPaths:withRowAnimation: 和/或-deleteRowsAtIndexPaths:withRowAnimation

          对于

          - numberOfSectionsInTableView:
          

          它应该返回一个等于和或结果的整数

          -insertRowsAtIndexPaths:withRowAnimation: 和/或 -deleteSections:withRowAnimation:

          【讨论】:

            【解决方案10】:

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

            【讨论】:

            • Core Data 也有这个问题。你能详细说明你的食谱吗?
            【解决方案11】:

            我刚刚在使用 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)
            
                        }
            

            【讨论】:

              【解决方案12】:

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

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 2014-11-19
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2019-11-02
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多