【问题标题】:NSArray filled from array attempt to insert nil object从数组填充的 NSArray 尝试插入 nil 对象
【发布时间】:2013-01-18 06:52:49
【问题描述】:

我尝试从现有填充数组中填充数组,但有时会出现此错误:

*** -[__NSPlaceholderArray initWithObjects:count:]: attempt to insert nil object from objects[4830]

此代码行导致的异常:

 NSArray *result = [NSArray arrayWithArray:self.testerLog];

testerLog 是 NSMutableArray,我用它从 App 收集日志。 下一条填充测试员日志:

[self.testerLog addObject:[NSString stringWithFormat:@"%@: %@ \n", [NSDate date], logRecord]];

它怎么会发生?当我将对象添加到 testerLog 并且尝试从此填充数组填充数组时失败时也不例外?

编辑: 关于初始化 testerLog。下面是 testerLog 方法的代码:

- (NSMutableArray *)testerLog {
    if (!_testerLog) {
        _testerLog = [NSMutableArray array];
    }

    return _testerLog;
}

所以我认为它不应该是零。

更新: 我忘了说将 NSString 添加到 testerLog 的方法可以从多个线程调用;

【问题讨论】:

  • self.testerLog 为零吗?你有没有初始化它?
  • @KurtRevis,在主帖中添加了初始化方法。错误还说不能插入 4830 对象,因为它是零。 testerLog 不应该是零。这就是为什么它对我来说如此奇怪

标签: ios nsarray


【解决方案1】:

您发布的吸气剂不是线程安全的。要获得等效的线程安全 getter,请改用以下代码。

-(NSMutableArray *)testerLog {

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{

        // If you're not using ARC you most definitely want to retain the array!
        // _testerLog = [[NSMutableArray array] retain]; 

        // If you're using ARC you should just assign
        _testerLog = [NSMutableArray array];
    });

    return _testerLog;
}

dispatch_once 调用确保无论您放入其中的任何代码,它都只会在您的应用程序的生命周期内执行一次(以线程安全的方式)。静态 onceToken 是标识特定块的内容。在您的特定情况下,这很有用,因为它保证数组仅实例化一次,无论有多少线程执行此 getter。

NON-ARC ONLY:保留是因为您希望数组在此方法执行后仍然存在(同样,仅当您不使用 ARC 时)。

此外,如果您不希望在某处看到 nil 值,因为这意味着存在一些逻辑错误:使用断言。以下是如何使用它们的示例:

assert(self.testerLog != nil);
NSArray *result = [NSArray arrayWithArray:self.testerLog];

【讨论】:

  • 谢谢。关于断言的好建议。关于问题:您对使用@synchronization 关键字添加日志有何看法?类似于:@synchronized(self.testerLog) { [self.testerLog addObject:logString]; }
  • 另外我认为问题不在测试仪日志数组的初始化中。例外是“尝试从对象 [4830] 插入零对象”,因此数组中的对象之一似乎是零。变成零。怎么会这样?
  • @Alexey - 如果您在多个线程中向同一个数组写入和读取字符串,您应该确保每次写入或读取时,您都是线程安全的.您确实可以尝试在此类代码周围添加@synchronized(self.testerLog) {<your_read_or_write_code>} 来尝试一下。
【解决方案2】:

确保您正确初始化了 testerLog 数组。它是 nil,这就是你的问题!

addObject 可能不会抛出错误,因为您正在尝试将有效的 NSString 添加到 testerLog 数组。尝试在添加对象的行之后立即在 self.testerLog 上执行 NSLog,并查看它是否按预期正确打印了 testerLog 数组。

【讨论】:

  • 在主帖中添加了初始化方法。 [self.testerLog addObject:] 也可以从多个线程调用。会不会导致错误?
猜你喜欢
  • 2023-03-29
  • 2017-12-16
  • 2012-08-09
  • 2016-05-23
  • 2020-11-08
  • 2012-10-30
  • 2014-08-27
  • 1970-01-01
  • 2013-04-28
相关资源
最近更新 更多