【问题标题】:attempt to insert nil object from objects[0]?尝试从 objects[0] 插入 nil 对象?
【发布时间】:2012-08-09 16:17:53
【问题描述】:

在我的应用程序中,我有一个 UITableView 和一些按钮,用户可以单击这些按钮根据一些 NSDate 或整数对数组进行排序。所以这是我尝试对 UITableView 进行排序的方法:

- (void)sortStats:(id)sender reloadData:(BOOL)dataBool {
    NSSortDescriptor *descriptor = nil;
    UIButton *clickedButton = (UIButton*)sender;
    if (clickedButton.tag == 1) {
            descriptor = [NSSortDescriptor sortDescriptorWithKey:@"Date" ascending:NO];
    }
    [self.cellArray sortUsingDescriptors:[NSArray arrayWithObject:descriptor]];
    [[NSUserDefaults standardUserDefaults] setObject:self.cellArray forKey:@"cellArray"];
    if (dataBool) {
        [ivstatstableView reloadData];
    }
    [ivstatstableView scrollRectToVisible:CGRectMake(0, 0, 1, 1) animated:YES];
}

所以最初我只是在没有 reloadData 参数的情况下使用了这个方法,因为 UITableView 上的 reloadData 似乎导致了崩溃。

这是控制台崩溃日志:

由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“*** -[__NSPlaceholderArray initWithObjects:count:]: 尝试从 objects[0] 插入 nil 对象”

无论如何,这里是否有任何代码会导致此崩溃?我真的很想让这个功能在我的应用程序中运行,我知道我即将修复它,但我不确定是什么导致了这个问题。

有什么想法吗?

【问题讨论】:

    标签: ios arrays uitableview null datasource


    【解决方案1】:

    这一切都很复杂,但有一点很突出:

    [[NSUserDefaults standardUserDefaults] setObject:self.cellArray 
                                              forKey:@"cellArray"];
    

    我认为您应该将其更改为:

    NSArray *array = [NSArray arrayWithArray:self.cellArray];
    [[NSUserDefaults standardUserDefaults] setObject:array forKey:@"cellArray"];
    

    其次,在您认为应该有对象的每个地方之后添加 asserts(),即:

    UIButton *theButton = ...
    assert(theButton);
    

    你也说行数是 cellArray 数的两倍,你猜这是故意的。

    【讨论】:

    • 为什么要将 setObject 行更改为您的?什么是推理,所以我理解逻辑。我也有意将 cellArray 计数乘以 2。
    • 因为 cellArray 是可变的,如果 userDefaults 只是保留它而不复制它(我不确定它的作用),那么如果你更改 cellArray,它会在复制用户默认值正在为您保留。
    【解决方案2】:

    至少有一个地方可能会发生这种情况,也许还有其他地方。在获取用户默认内容的代码中,您不检查nil。所以不要这样:

    [self.cellArray addObjectsFromArray:[[NSUserDefaults standardUserDefaults] objectForKey:@"array"]];
    

    你可能想试试这个:

    NSArray *defaultCellArray = [[NSUserDefaults standardUserDefaults] objectForKey:@"array"];
    if (defaultCellArray) {
        [self.cellArray addObjectsFromArray:defaultCellArray];
    }
    

    也有可能失败的initWithObjects 调用(根据您的错误消息)嵌套在另一个调用中,也许在这个调用中:

    [self.cellArray sortUsingDescriptors:[NSArray arrayWithObject:descriptor]];
    

    如果您查看完整的调用堆栈,它会告诉您此调用是否正在对initWithObjects 进行后续调用,并可能将nil 传递给它。例如,在您的情况下,如果 clickedButton.tag 尚未设置为值 1 或 2,您将传入一个 nil yo 您正在创建的数组。您可能需要添加一个额外的 else 子句来帮助诊断问题:

    if (clickedButton.tag == 1) {
            descriptor = [NSSortDescriptor sortDescriptorWithKey:@"Date" ascending:NO];
    } else if (clickedButton.tag == 2) {
            descriptor = [NSSortDescriptor sortDescriptorWithKey:@"Score" ascending:NO];
    } else {
        NSLog(@"Unexpected error: Can't determine sort descriptor");
    }
    

    【讨论】:

    • 每当我调用 sortUsingDesriptors 行时,它只会在 self.cellArray.count 不 = 0 时执行。我还修复了标签问题,因此描述符可以正确初始化,但我仍然得到相同的结果碰撞。 self.cellArray 不是 nil 并且它的计数为 2 或更多(1 或更少它不会被我的条件调用)。还有什么问题?
    • 很难说 - 您应该向我们展示更多完整的堆栈跟踪,以确定问题出在代码的哪个位置。另外,您是否输入了我建议的检查以确保您从 NSUserDefaults 返回非零值?
    猜你喜欢
    • 2012-10-30
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-23
    • 2021-01-04
    • 1970-01-01
    • 2014-08-27
    相关资源
    最近更新 更多