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 没有。错误或功能?的主要内容,如果未能解决你的问题,请参考以下文章