0

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

*** -[__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 的方法可以从多个线程调用;

4

2 回答 2

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某处看到值,因为这意味着存在一些逻辑错误:使用 assertions。以下是如何使用它们的示例:

assert(self.testerLog != nil);
NSArray *result = [NSArray arrayWithArray:self.testerLog];
于 2013-01-18T11:28:33.407 回答
0

确保您正确初始化了 testerLog 数组。它为零,这导致了您的问题!

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

于 2013-01-18T07:15:01.443 回答