I have to disagree with bbum's answer on this. A NSPointerArray
is an array, not a sparse array, and there are important differences between the two.
I strongly recommend that bbums solution not be used.
The documentation for NSPointerArray
is available here.
Cocoa already has an array object as defined by the NSArray
class. NSPointerArray
inherits from NSObject
, so it is not a direct subclass of NSArray
. However, the NSPointerArray
documentation defines the class as such:
NSPointerArray is a mutable collection modeled after NSArray but it can also hold NULL values
I will make the axiomatic assumption that this definition from the documentation asserts that this is a "logical" subclass of NSArray
.
Definitions-
A "general" array is: a collection of items, each of which has a unique index number associated with it.
An array, without qualifications, is: A "general" array where the indexes of the items have the following properties: Indexes for items in the array begin at 0
and increase sequentially. All items in the array contains an index number less than the number of items in the array. Adding an item to an array must be at index + 1 of the last item in the array, or an item can be inserted in between two existing item index numbers which causes the index number of all subsequent items to be incremented by one. An item at an existing index number can be replaced by another item and this operation does not change the index numbers of the existing operations. Therefore, insert and replace are two distinct operations.
A sparse array is: A "general" array where the index number of the first item can begin at any number and the index number of subsequent items added to the array has no relation to or restrictions based on other items in the array. Inserting an item in to a sparse array does not effect the index number of other items in the array. Inserting an item and replacing an item are typically synonymous in most implementations. The count of the number of items in the sparse array has no relationship to the index numbers of the items in the sparse array.
These definitions make certain predictions about the behavior of a "black box" array that are testable. For simplicity, we'll focus on the following relationship:
In an array, the index number of all the items in the array is less than the count of the number of items in the array. While this may be true of a sparse array, it is not a requirement.
In a comment to bbum, I stated the following:
a NSPointerArray
is not a sparse array, nor does it behave like one. You still have to fill all the unused indexes with NULL
pointers. Output from [pointerArray insertPointer:@"test" atIndex:17];
on a freshly instantiated NSPointerArray
:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSConcretePointerArray insertPointer:atIndex:]: attempt to insert pointer at index 17 beyond bounds 0'
It is stated, without proving, the the behavior of NSPointerArray
above violates the very definition of a sparse array. This part of the error message is revealing: attempt to insert pointer at index 17 beyond bounds 0'
, in particular the part about having to add the first new item at index 0
.
bbum then comments:
That is incorrect. You failed to call -setCount: to set the capacity to a sufficient size.
It is non-sensical to "set the count" of the number of items in a sparse array. If NSPointerArray
was a sparse array, one would expect that after adding the first item at index 17, the count of the number of items in the NSPointerArray
would be one. However, following bbums advice, the number of items in the NSPointerArray
after adding the first items is 18
, not 1
.
QED- It is shown that a NSPointerArray
is in fact an array, and for the purposes of this discussion, a NSArray
.
Additionally, bbum makes the following additional comments:
NSPointerArray most certainly does support holes.
This is provably false. An array requires all items contained in it to contain something, even if that something is 'nothing'. This is not true of a sparse array. This is the very definition of a 'hole' for the purposes of this discussion. A NSPointerArray
does not contain holes
in the sparse array sense of the term.
That was one of the whole points of writing the class. You have to set the count first.
It is provably non-sensical to "set the count" of a sparse array.
Whether the internal implementation is a sparse array or a hash or, etc, is an implementation detail.
This is true. However, the documentation for NSPointerArray
does not make any reference to how it implements or manages its array of items. Furthermore, it does not state anywhere that a NSPointerArray
"efficiently manages an array of NULL pointers."
QED- bbum is depending on the undocumented behavior that a NSPointerArray
efficiently handles NULL
pointers via a sparse array internally. Being undocumented behavior, this behavior can change at any time, or may not even apply to all uses of the NSPointerArray
. A change in this behavior would be catastrophic if the highest index number stored in it are sufficiently large (~ 2^26).
And, in fact, it is not implemented as one big hunk of memory...
Again, this is a private implementation detail that is undocumented. It is extremely poor programming practice to depend on this type of behavior.