7

我有一种情况,我希望能够维护一个可能都指向 nil 的指针数组。

Equipment *equipment[19];

但是,我发现我不能将指针数组或双指针设置为对象的属性。

当我不能使用 C 样式数组时,我的解决方法是使用 NSArray 对象。因此,我尝试执行以下操作:

NSMutableArray *equipment = [NSMutableArray arrayWithCapacity: NUM_EQUIPSLOTS];
for (int i=0; i<NUM_EQUIPSLOTS; i++) {
    [equipment setObject: nil atIndexedSubscript: i];
}

这里的想法是我有一个空指针数组,稍后将指向东西。

*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:
(0x246e012 0x1e4be7e 0x2421b6a 0x2421a20 0xebd02 0xde82b 0xc9d5a 0xcb6bd 0x4d525 0xc94fa 0xc8b6a 0xa18157 0xa18747 0xa1994b 0xa2acb5 0xa2bbeb 0xa1d698 0x3176df9 0x3176ad0 0x23e3bf5 0x23e3962 0x2414bb6 0x2413f44 0x2413e1b 0xa1917a 0xa1affc 0xc8526 0x1fa5)
libc++abi.dylib: terminate called throwing an exception

我知道我可以很容易地使用 C 风格的数组和单个对象来做到这一点。我宁愿这样做而不是像这样愚蠢的事情:

Equipment *equipment0 = nil;
Equipment *equipment1 = nil;
Equipment *equipment2 = nil;
// ...
Equipment *equipment18 = nil;

这可能与 NSArray 模型本身的结构有关。有人会向我解释为什么会这样,以及为什么我不能简单地在 NSArray 中添加或设置 nil 对象吗?先感谢您。

4

2 回答 2

10

“为什么”既琐碎又令人不满意。这是因为NSMutableArray持有对象,而nil不是对象。ObjC 在对象和原始类型之间有很大的区别。nil是原始类型。作为CodaFi注释,您可以使用NSNullNSPointerArray来解决这些问题。典型的解决方案是NSNull

于 2013-03-28T01:05:49.670 回答
5

没有充分的理由。NSArrayNSMutableArray存储指向对象的指针。nil是一个体面的指向对象的指针。Java 的等价物是ArrayList,它确实允许null元素。这只是一个设计选择。

这种设计选择的一个可能的历史原因是创建数组并用元素填充它的最常见方法是使用-initWithObjects:...or+arrayWithObjects:...方法,它使用可变参数来获取用户想要提供的尽可能多的参数并将其放入数组中. 由于在 C 中使用 varargs,不可能确定参数的数量,他们选择指示有多少nil作为“终止符”来表示列表结束的方式。(还有其他表示数字的方法,例如将数字作为第一个参数传递。)这种方法的缺点是您不能将nil其作为要放入数组的“参数”之一,因为它会终止名单。

但是,这些方法并不是创建数组并用元素填充它的唯一方法。您可以创建一个空数组并分别添加每个数组,或者您可以使用-initWithObjects:count:or+arrayWithObjects:count:方法,它们不是可变参数,因此没有nil终止符问题。现在,还有数组字面量语法(在-initWithObjects:count:内部调用),这使它变得更加容易。完全可以想象拥有NSArray并且NSMutableArray允许nil元素;只是你不能使用-initWithObjects:...+arrayWithObjects:...添加nil元素。然而,他们选择不这样做。

于 2013-03-28T04:44:07.387 回答