从 tableview 部分删除最后一行时,iOS 应用程序崩溃

Posted

技术标签:

【中文标题】从 tableview 部分删除最后一行时,iOS 应用程序崩溃【英文标题】:iOS app crashes when deleting the last row from a tableview section 【发布时间】:2012-03-12 04:34:21 【问题描述】:

我正在学习可编辑的分段 UITableView,但我无法弄清楚为什么我的应用在删除其中一个部分的最后一行时会崩溃。我一直在这里和谷歌搜索,在我看来,我已经完成了大多数人所说的解决这个问题的方法,但没有运气。我为所提供的任何帮助感到困惑和感激。

这是我删除表格行的方法

myTableSections 是一个 NSMutableArray,其中包含代表部分的 NSDictionaries - “Possessions”是保存行数组的键,以及部分标题的键“Header”

PossessionStore 是一个单例,在 allPossessions 数组中保存应用程序的所有 Possession

divideSections 的 msg 是一种将 allPossessions 排序为 NSDictionaries 并将它们存储到 myTableSections 中的方法

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
       ////If the table view is asking to commit the delete command
    if (editingStyle == UITableViewCellEditingStyleDelete) 

        // Get the possesion from the row
        Possession *p = [[[myTableSections objectAtIndex:[indexPath section]] objectForKey:@"Possessions"] objectAtIndex:[indexPath row]];

        // delete it from the PossessionStore
        [[[PossessionStore defaultStore] allPossessions] removeObjectIdenticalTo:p];

        // Rebuild myTableViewSections to reflect the data change to the PossessionStore
        [self divideSections];

            // remove the row from the table view with an animation
        [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
    

哦,是的,几乎忘记了最后一部分 - 调试信息 - 此时第 1 部分中有两行,第 2 部分中有一行。然后我从第 1 部分中删除一行,然后从第 1 部分中删除最后一行。根据我输入的 NSLog 报告和错误消息部分计数是正确的,因为它应该在那个时候是正确的,但它没有显示该部分被删除。如果我理解正确?????????

2012-03-12 00:40:49.938 HomePwnr[53434:f803] commitEditingStyle:forRowAtIndexPath: called
2012-03-12 00:40:49.940 HomePwnr[53434:f803] myTableSections is holding - (
        
        Header = "Cheap Stuff";
        Possessions =         (
            "Red Car (2U8F9): Worth $20, recorded on 2012-03-12 04:40:38 +0000",
            "Blue Gun (0X2Q7): Worth $14, recorded on 2012-03-12 04:40:40 +0000"
        );
    ,
        
        Header = "Expensive Stuff";
        Possessions =         (
            "Blue Mac (7R3K0): Worth $97, recorded on 2012-03-12 04:40:36 +0000"
        );
    
)
2012-03-12 00:40:49.942 HomePwnr[53434:f803] divideSections called
2012-03-12 00:40:49.944 HomePwnr[53434:f803]  End of divideSections myTableSections is holding - (
        
        Header = "Cheap Stuff";
        Possessions =         (
            "Red Car (2U8F9): Worth $20, recorded on 2012-03-12 04:40:38 +0000"
        );
    ,
        
        Header = "Expensive Stuff";
        Possessions =         (
            "Blue Mac (7R3K0): Worth $97, recorded on 2012-03-12 04:40:36 +0000"
        );
    
)
2012-03-12 00:40:49.946 HomePwnr[53434:f803] returning number of sections: 2
2012-03-12 00:40:49.947 HomePwnr[53434:f803] returning number of sections: 2
2012-03-12 00:40:49.949 HomePwnr[53434:f803] tableView:titleForHeaderInSectionCalled - section = 0
2012-03-12 00:40:49.951 HomePwnr[53434:f803] tableView:titleForHeaderInSectionCalled - section = 0
2012-03-12 00:40:49.953 HomePwnr[53434:f803] tableView:numberOfRowsInSection called for section 0, returning - 1
2012-03-12 00:40:49.954 HomePwnr[53434:f803] tableView:titleForHeaderInSectionCalled - section = 1
2012-03-12 00:40:49.956 HomePwnr[53434:f803] tableView:titleForHeaderInSectionCalled - section = 1
2012-03-12 00:40:49.957 HomePwnr[53434:f803] tableView:numberOfRowsInSection called for section 1, returning - 1
2012-03-12 00:41:32.232 HomePwnr[53434:f803] commitEditingStyle:forRowAtIndexPath: called
2012-03-12 00:41:32.234 HomePwnr[53434:f803] myTableSections is holding - (
        
        Header = "Cheap Stuff";
        Possessions =         (
            "Red Car (2U8F9): Worth $20, recorded on 2012-03-12 04:40:38 +0000"
        );
    ,
        
        Header = "Expensive Stuff";
        Possessions =         (
            "Blue Mac (7R3K0): Worth $97, recorded on 2012-03-12 04:40:36 +0000"
        );
    
)
2012-03-12 00:41:32.236 HomePwnr[53434:f803] divideSections called
2012-03-12 00:41:32.238 HomePwnr[53434:f803]  End of divideSections myTableSections is holding - (
        
        Header = "Expensive Stuff";
        Possessions =         (
            "Blue Mac (7R3K0): Worth $97, recorded on 2012-03-12 04:40:36 +0000"
        );
    
)
2012-03-12 00:41:32.239 HomePwnr[53434:f803] returning number of sections: 1
2012-03-12 00:41:32.241 HomePwnr[53434:f803] returning number of sections: 1
2012-03-12 00:41:32.242 HomePwnr[53434:f803] tableView:titleForHeaderInSectionCalled - section = 0
2012-03-12 00:41:32.244 HomePwnr[53434:f803] tableView:titleForHeaderInSectionCalled - section = 0
2012-03-12 00:41:32.246 HomePwnr[53434:f803] tableView:numberOfRowsInSection called for section 0, returning - 1
2012-03-12 00:41:32.248 HomePwnr[53434:f803] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-1914.84/UITableView.m:1021
2012-03-12 00:41:32.250 HomePwnr[53434:f803] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections.  The number of sections contained in the table view after the update (1) must be equal to the number of sections contained in the table view before the update (2), plus or minus the number of sections inserted or deleted (0 inserted, 0 deleted).'
*** First throw call stack:
(0x13cc022 0x155dcd6 0x1374a48 0x9ad2cb 0x9b103 0xa66d2 0xa674d 0x3409 0xb26e2 0x208e6b 0x13cde99 0x1914e 0x190e6 0xbfade 0xbffa7 0xbf266 0x3e3c0 0x3e5e6 0x24dc4 0x18634 0x12b6ef5 0x13a0195 0x1304ff2 0x13038da 0x1302d84 0x1302c9b 0x12b57d8 0x12b588a 0x16626 0x20dc 0x2085)
terminate called throwing an exception(lldb) 

【问题讨论】:

能否请您发布崩溃日志,以便了解问题崩溃日志将发挥至关重要的作用:) 确保表中的数组显示它是可变的。如果它不是“NSMutableArray”,则不能从中添加/删除。 数组是可变的,并且正在根据 NSLOG 语句进行更新。谢谢。还有什么? ***.com/questions/1061071/… 可以帮到你 【参考方案1】:

所有 UITableview 部分必须至少有一行。

因此,当您要删除最后一行时,您必须改为删除该部分:

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

确保您的数据正确处理空部分(在提供部分数量等时)

【讨论】:

我也试过这个。根据调试器中的我的 NSLogs,部分计数都在相应地处理。每次删除都会重建我保存这些部分的数组。因此,应始终返回节数和行数以反映 myTableSections 的当前状态。我觉得?????? 根据日志(和您的代码),该部分永远不会被删除。对于该部分的最后一行,您必须调用 deleteSections 而不是 deleteRowsAtIndexPaths。【参考方案2】:

向昨晚为我指明正确方向的所有人道歉。我太累了,太沮丧了,我已经把头撞得太久了。这是我修复它的最终解决方案。

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
       ////If the table view is asking to commit the delete command
    if (editingStyle == UITableViewCellEditingStyleDelete) 
        BOOL lastRow = FALSE;
        if ([tableView numberOfRowsInSection:[indexPath section]] == 1 ) 
            lastRow = TRUE;
               
        // Get the possesion from the row
        Possession *p = [[[myTableSections objectAtIndex:[indexPath section]] objectForKey:@"Possessions"] objectAtIndex:[indexPath row]];

        // delete it from the PossessionStore
        [[[PossessionStore defaultStore] allPossessions] removeObjectIdenticalTo:p];

        // Rebuild myTableViewSections to reflect the data change to the PossessionStore
        [self divideSections];

            // remove the row or section if last row from the table view with an animation
        if (lastRow) 
            // NSLog(@"Should be deleting section");
            [tableView deleteSections:[NSIndexSet indexSetWithIndex:indexPath.section] withRowAnimation:YES];
         else 
            // NSLog(@"Should be deleting row");
            [tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:YES];
        
    

【讨论】:

完美,这正是我在回答中所说的你需要做的。很高兴它有效! 是的,我只是需要休息一下,然后恢复精神。当你在比菜鸟稍微好一点的地方时会感到非常沮丧,但还有很多东西要学,而且你不知道你认为自己应该能够做什么。 我想你要小心 withRowAnimation 参数。它不应该是 YES 或 NO,而是 UITableViewRowAnimationNone 或不同的 UITableViewRowAnimation 值。 这为我节省了很多时间。感谢您和 Inafziger。

以上是关于从 tableview 部分删除最后一行时,iOS 应用程序崩溃的主要内容,如果未能解决你的问题,请参考以下文章

tableview 删除部分中的最后一行

从 tableView 中删除一行,在 section 中有多行

从部分移动最后一行时如何删除部分标题

ios中怎么判断是不是滚动到tableview的最后一行

iOS Swift 2 - 删除 tableView 行时出错

当键盘出现iOS时向上滚动tableview行