从UITableView删除多个选择会在滚动后抛出异常(重用问题?)

时间:2015-06-28 18:35:03

标签: ios uitableview reuseidentifier

我试图从表格视图中删除多个选项。一切正常,直到我向上或向下滚动,然后它崩溃并抛出异常。

from kivy.app import App
from kivy.uix.tabbedpanel import TabbedPanel
from kivy.lang import Builder

Builder.load_string("""

<Test>:
    do_default_tab: False
    tab_width: self.size[0]/len(self.tab_list)
    TabbedPanelItem:
        text: 'tab 1'
    TabbedPanelItem:
        text: 'tab2'

    TabbedPanelItem:
        text: 'tab3'
""")

class Test(TabbedPanel):
    pass

class TabbedPanelApp(App):
    def build(self):
        return Test()

if __name__ == '__main__':
    TabbedPanelApp().run()

对象不能为零

这是我删除对象的方式:

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'

同样这一切都运行正常,除非我向上/向下滚动以选择/取消选择更多单元格,因此我将我的单元格子类化,因为我读到了不能在SO上重复使用单元格。

供参考:

- (IBAction)deleteObjects:(id)sender {

    NSArray *selectedRows = [self.tableView indexPathsForSelectedRows];

    BOOL deleteSpecificRows = selectedRows.count > 0;
    if (deleteSpecificRows)
    {
        NSMutableArray *stringsOfObjects = [NSMutableArray new];
        for (NSIndexPath *selectionIndex in selectedRows) {
            UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:selectionIndex];
            [stringsOfObjects addObject:cell.textLabel.text];
        }

        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *path = [paths objectAtIndex:0];
        NSString *plistPath = [path stringByAppendingPathComponent:@"AlertSubscriptions.plist"];
        NSMutableArray *array = [[[NSMutableArray alloc] initWithContentsOfFile:plistPath] mutableCopy];

        [array removeObjectsInArray:stringsOfObjects];
        [self.alertSubArray removeObjectsInArray:stringsOfObjects];
        [array writeToFile:plistPath atomically:YES];

     [self.tableView deleteRowsAtIndexPaths:selectedRows withRowAnimation:UITableViewRowAnimationAutomatic];
    }

我曾尝试使用静态细胞而不使用静态细胞。我已经尝试将dequeueReusableCellWithIdentifier设置为静态单元格而没有。当我滚动

时都不起作用
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

SubscriptionsTableViewCell *cell = [tableView
                              dequeueReusableCellWithIdentifier:nil];
if (cell == nil) {
    cell = [[SubscriptionsTableViewCell alloc]
            initWithStyle:UITableViewCellStyleDefault
            reuseIdentifier:nil];
}

    cell.textLabel.text = [self.alertSubArray objectAtIndex:indexPath.row];
    cell.textLabel.textAlignment = NSTextAlignmentLeft;

    return cell;
}

错误日志:

static NSString *CellIdentifier = @"Cell";

修改 所以在尝试了其他人告诉我做的事后,我做了以下事情:

设置异常断点。崩溃后填充的行是2015-06-28 15:46:19.379 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil' *** First throw call stack: (0x186d3c2d8 0x1985680e4 0x186c234c0 0x10017e7d8 0x18b7b1404 0x18b79a4e0 0x18b7b0da0 0x18b7b0a2c 0x18b7a9f68 0x18b77d18c 0x18ba1e324 0x18b77b6a0 0x186cf4240 0x186cf34e4 0x186cf1594 0x186c1d2d4 0x1904336fc 0x18b7e2fac 0x1001646d4 0x198be6a08) libc++abi.dylib: terminating with uncaught exception of type NSException 行。

我确保我的[stringsOfObjects addObject:cell.textLabel.text];方法现已正确设置:

cellForRowAtIndexPath

之后我仍然在将对象添加到NSMutableArray时崩溃,所以我查看调试器并确保我的UITableViewCell不像我提到的机器人那样,它看起来像是但我不是&# 39;知道从哪里开始:因为在我看来它不是零

image1

如您所见,我选择了6行,但只添加了2个对象。我不知道为什么这么困难,为什么有些不是没有?为什么我可以完全删除它们而无需滚动选择更多?

1 个答案:

答案 0 :(得分:2)

因此,经过评论中的广泛讨论后,问题似乎如下:

[stringsOfObjects addObject:cell.textLabel.text];方法中deleteObjects:的逻辑是错误的。这是因为它直接从单元格而不是填充单元格的数组后备存储中获取文本。

单元格可以在屏幕外滚动并重新使用,因此其中的文本不再正确,事实上,单元格不再存在&#34;因为它已被重用。如果细胞不存在&#34;将创建一个空单元格,其中文本字段可能为nil。注意细胞再利用是一件好事;不要创建单元格,也不要重复使用它们,否则你的内存会快速耗尽。

相反,从后备存储中获取文本,该文本将填充单元格本身而不是直接填充单元格。我希望代码类似于:

[stringsOfObjects addObject:[self.alertSubArray objectAtIndex:selectionIndex.row]];