崩溃:commitEditingStyle -deleteObject 为零

Posted

技术标签:

【中文标题】崩溃:commitEditingStyle -deleteObject 为零【英文标题】:Crash :commitEditingStyle -deleteObject is nil 【发布时间】:2014-04-03 10:39:46 【问题描述】:

我的应用程序的一些用户正在使用我的 TableView 崩溃,它使用 NSFetchedResultsController 从 Core Data 获取数据源。我的视图控制器是CoreDataTableViewController 的子类,它在UITableViewController 中包含 NSFetchedResultsController 的标准代码。 崩溃报告说崩溃发生在tableView:commitEditingStyle:forRowAtIndexPath:] 行(代码就在下面),原因如下:

致命异常:NSInvalidArgumentException -deleteObject:需要一个非零参数

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

    if (editingStyle == UITableViewCellEditingStyleDelete) 

        [self.managedObjectContext deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];

    

我试图寻找类似的问题,但我没有找到任何东西,而且它并不总是发生(在测试期间从未遇到过)。

这是我的CoreDataTableViewController 类中的 didChangeObject:

- (void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath

    if (!self.suspendAutomaticTrackingOfChangesInManagedObjectContext)
    
        switch(type)
        
            case NSFetchedResultsChangeInsert:
                [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;

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

            case NSFetchedResultsChangeUpdate:
                [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;

            case NSFetchedResultsChangeMove:
                [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                break;
        
    

谁能帮帮我?

【问题讨论】:

这可能是因为 tableView 被传递给方法 tableView:commitEditingStyle:forRowAtIndexPath:] 被释放。如果你确定它没有被释放,那么我会建议你在代码中添加异常断点然后测试它。 你到底在用suspendAutomaticTrackingOfChangesInManagedObjectContext做什么?当看到崩溃时,您是否询问用户他们在做什么? @Wain 我只是从 Crashlytics 获取崩溃报告,仅此而已。 【参考方案1】:

这里有一些你不会看到记录的东西,但它有时是正确的:在极少数情况下,这条消息可能会被触发两次。如果是,第二次indexPath 将是nil

处理此问题的适当方法是首先检查nil

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

    if (editingStyle == UITableViewCellEditingStyleDelete) 

        if (indexPath == nil) return;

        [self.managedObjectContext deleteObject:[self.fetchedResultsController objectAtIndexPath:indexPath]];

    

几个月来(可能是几年?),我在删除例程中遇到了类似的崩溃,但我永远无法解决这个问题。直到有一天,我很幸运,它发生在我删除带有调试器的行时。我能够看到 indexPath 出乎意料地是 nil,并且我的项目数组已经为空。

这意味着事件要么连续触发两次,要么操作系统再次调用它以响应用户在删除最后一项后执行的某些操作。我一直无法找出是哪一个,而且我还没有看到它再次发生。但是,它解释了我看到的一些崩溃报告。

【讨论】:

以上是关于崩溃:commitEditingStyle -deleteObject 为零的主要内容,如果未能解决你的问题,请参考以下文章

尝试从UITableView中删除行时有时崩溃

commitEditingStyle 中的 NSIndexPath

在 commitEditingStyle 中删除 NSManagedObject

在 iPhone 的 Objective-C 中在 (commitEditingStyle) 之外调用 (deleteRowsAtIndexPaths)

UITableView 删除行,commitEditingStyle 方法没有触发?

UICollectionView如何删除单元格(相当于commitEditingStyle)?