NSArrayWithObject:nil 断言,但 NSArrayWithObjects:nil 没有。错误或功能?

Posted

技术标签:

【中文标题】NSArrayWithObject:nil 断言,但 NSArrayWithObjects:nil 没有。错误或功能?【英文标题】:NSArrayWithObject:nil asserts, but NSArrayWithObjects:nil doesn't. Bug or feature? 【发布时间】:2014-10-11 00:10:56 【问题描述】:

在调试 UICollectionView -reloadItemsAtIndexPaths 的问题时,我将断言跟踪到我(通常)需要将此方法传递给单个元素数组(我只有一个要重新加载的单元格)的条件。因此,很明显,我使用了下面的等价物来生成必要的数组:

NSIndexPath *foo = ...
NSArray *bar = [NSArray arrayWithObject:foo];
[mycollectionview reloadItemsAtIndexPaths:bar];

但是,在 mycollectionview 仍然为空的特殊情况下,indexpath foo 为 nil(即没有要重新加载的单元格),它会出现 arrayWithObject: 断言错误:

2014-10-11 12:45:08.066 Xulu[26594:90b] * 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“* -[__NSPlaceholderArray initWithObjects:count:]:尝试从 objects[0]' 中插入 nil 对象

但是,如果我改为使用

NSArray *bar = [NSArray arrayWithObjects:foo,nil];

一切都很好。

所以我的问题是,[NSArray arrayWithObject:nil] 是断言错误还是未记录的功能? Apple 文档没有说明参数必须为非零。我看到很多关于在 arrayWithObjects 中使用 nil 的帖子,但没有关于 arrayWithObject 和 nil 的帖子。这似乎是一个不那么不寻常的情况......

【问题讨论】:

arrayWithObjects 需要一个以 nil 结尾的列表。 NSArray 中不能有 nil 值。 【参考方案1】:

根据定义,arrayWithObject 的参数必须是一个指针,它作为NSArray 的元素是合法的。 NSArray 不能包含 nil,因此将 nil 传递给此方法是设计错误 — 因此出现异常。

另一方面,arrayWithObjects 采用以零结尾的参数列表。单独传递 nil 构成传递一个空列表,创建一个空数组。没有错。

但是,在现代 ObjC 中,最好不要使用任何一种方法。相反,使用数组文字:

NSArray *bar = @[foo];

这使您的代码的未来读者更清楚您的意图,通过更清晰的错误消息捕获有问题的 nil 使用,并避免因使用 arrayWithObjects 和意外的 nil 而导致的那种静默失败。

【讨论】:

感谢您的建议!【参考方案2】:

您不能将 nil 放入数组 - 您必须存储一个 NSNull 对象

NSArray *bar = [NSArray arrayWithObjects:foo,nil];

创建一个包含 foo 的单元素数组 - nil 是指示要放入数组的对象列表末尾的标记 - 它不会放入数组中

现在,如果foo 本身为 nil,那么这和说的一样

NSArray *bar = [NSArray arrayWithObjects:nil,nil];  

第一个 nil 终止列表,第二个 nil 被忽略 - 所以你最终得到一个空数组

NSArray *bar = [NSArray arrayWithObject:foo];

创建一个单元素数组并将指定的对象放入其中 - 但是您的对象是 nil 并且您不能存储 nil 所以您会遇到断言失败。

【讨论】:

【参考方案3】:

为了跟进我自己的问题,在进一步挖掘之后——代替上面的 cmets——这可能是按设计工作的;即一个可以说是记录不充分的“功能”,而不是一个错误......特别是,Apple 的 insertObjectAtIndex: 文档确实明确指出:

(void)insertObject:(id)anObject atIndex:(NSUInteger)index

参数

一个对象

要添加到数组内容的对象。此值不能为 nil。

重要提示:如果 anObject 为 nil,则引发 NSInvalidArgumentException。

arrayWithObject: 文档可能会受益于类似的东西。感谢那些花时间做出回应的人。这可以关闭。

【讨论】:

以上是关于NSArrayWithObject:nil 断言,但 NSArrayWithObjects:nil 没有。错误或功能?的主要内容,如果未能解决你的问题,请参考以下文章

jmter添加断言

正则断言详解

Jmeter之断言(3种)

[接口测试_B] 03 Pytest断言处理_assert和异常断言

jmeter怎么做断言

jmeter断言为整数怎么表达