我不得不不同意bbum对此的回答。ANSPointerArray
是数组,不是稀疏数组,两者有重要区别。
我强烈建议不要使用 bbums 解决方案。
的文档NSPointerArray
可在此处获得。
Cocoa 已经有一个类定义的数组对象NSArray
。 NSPointerArray
继承自NSObject
,因此它不是 的直接子类NSArray
。但是,NSPointerArray
文档将类定义为:
NSPointerArray is a mutable collection modeled after NSArray but it can also hold NULL values
我将做出一个公理假设,即文档中的这个定义断言这是NSArray
.
定义-
“通用”数组是:项目的集合,每个项目都有一个唯一的索引号与之关联。
一个没有限定条件的数组是: 一个“通用”数组,其中项的索引具有以下属性: 数组中项的索引开始于0
并按顺序增加。数组中的所有项包含的索引号小于数组中的项数。向数组中添加项必须在数组中最后一项的索引 + 1 处,或者可以在两个现有项索引号之间插入一个项,这会导致所有后续项的索引号加一。现有索引号的项目可以被另一个项目替换,此操作不会更改现有操作的索引号。因此,插入和替换是两个不同的操作。
稀疏数组是:一个“一般”数组,其中第一项的索引号可以从任意数字开始,并且添加到数组中的后续项的索引号与数组中的其他项没有关系或限制。将项目插入稀疏数组不会影响数组中其他项目的索引号。在大多数实现中,插入项目和替换项目通常是同义词。稀疏数组中项的计数与稀疏数组中项的索引号无关。
这些定义对可测试的“黑盒”数组的行为做出了某些预测。为简单起见,我们将关注以下关系:
在数组中,数组中所有项的索引号小于数组中项数的计数。虽然这可能适用于稀疏数组,但这不是必需的。
在对 bbum 的评论中,我陈述了以下内容:
aNSPointerArray
不是稀疏数组,它的行为也不像一个。您仍然必须用NULL
指针填充所有未使用的索引。来自[pointerArray insertPointer:@"test" atIndex:17];
新实例化的输出NSPointerArray
:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSConcretePointerArray insertPointer:atIndex:]: attempt to insert pointer at index 17 beyond bounds 0'
据说,没有证明,上述行为NSPointerArray
违反了稀疏数组的定义。错误消息的这一部分揭示了:attempt to insert pointer at index 17 beyond bounds 0'
,特别是关于必须在 index 处添加第一个新项目的部分0
。
bbum 然后评论:
这是不正确的。您未能调用 -setCount: 将容量设置为足够的大小。
对稀疏数组中的项目数进行“设置计数”是没有意义的。如果NSPointerArray
是一个稀疏数组,人们会期望在索引 17 处添加第一个项目后,其中项目数的计数NSPointerArray
将为 1。但是,按照 bbums 的建议,NSPointerArray
添加第一个项目后的项目数是18
,而不是1
。
QED- 表明 aNSPointerArray
实际上是一个数组,为了讨论的目的, a NSArray
。
此外,bbum 还提出了以下附加评论:
NSPointerArray 肯定支持漏洞。
这可证明是错误的。数组要求其中包含的所有项目都包含某些内容,即使该内容是“无”。这不适用于稀疏数组。出于本讨论的目的,这正是“洞”的定义。ANSPointerArray
不包含holes
术语的稀疏数组意义。
这是编写课程的全部要点之一。您必须先设置计数。
对稀疏数组“设置计数”可证明是没有意义的。
内部实现是稀疏数组还是散列等,是实现细节。
这是真的。但是,文档NSPointerArray
没有提及它如何实现或管理其项目数组。此外,它没有在任何地方说明NSPointerArray
“有效地管理空指针数组”。
QED-bbum 依赖于内部通过稀疏数组有效处理指针的未记录行为。作为未记录的行为,此行为可能随时更改,甚至可能不适用于. 如果存储在其中的最高索引号足够大(~ 2^26),那么这种行为的变化将是灾难性的。NSPointerArray
NULL
NSPointerArray
而且,事实上,它并没有作为一大块内存来实现......
同样,这是一个未记录的私有实现细节。依赖这种类型的行为是非常糟糕的编程实践。