これに関するbbumの答えには同意できません。ANSPointerArray
はスパース配列ではなく配列であり、この 2 つには重要な違いがあります。
bbums ソリューションを使用しないことを強くお勧めします。
のドキュメントは、こちらからNSPointerArray
入手できます。
NSArray
Cocoa には、クラス で定義された配列オブジェクトが既にあります。NSPointerArray
から継承しNSObject
ているため、 の直接のサブクラスではありませんNSArray
。ただし、NSPointerArray
ドキュメントではクラスを次のように定義しています。
NSPointerArray is a mutable collection modeled after NSArray but it can also hold NULL values
ドキュメントからのこの定義は、これがNSArray
.
定義-
「一般的な」配列とは、アイテムのコレクションであり、それぞれに固有のインデックス番号が関連付けられています。
修飾なしの配列は次のとおりです: 項目のインデックスが次のプロパティを持つ「一般的な」配列: 配列内の項目のインデックスは で始まり、0
順次増加します。配列内のすべての項目には、配列内の項目数よりも小さいインデックス番号が含まれています。配列への項目の追加は、配列内の最後の項目のインデックス + 1 である必要があります。または、2 つの既存の項目インデックス番号の間に項目を挿入して、後続のすべての項目のインデックス番号を 1 ずつ増やすことができます。既存のインデックス番号の項目は別の項目に置き換えることができ、この操作は既存の操作のインデックス番号を変更しません。したがって、挿入と置換は 2 つの異なる操作です。
スパース配列は次のとおりです。最初の項目のインデックス番号が任意の番号で開始でき、配列に追加される後続の項目のインデックス番号が、配列内の他の項目との関係や制限を持たない「一般的な」配列です。スパース配列に項目を挿入しても、配列内の他の項目のインデックス番号には影響しません。通常、アイテムの挿入とアイテムの置換は、ほとんどの実装で同義です。疎配列内の項目数のカウントは、疎配列内の項目のインデックス番号とは関係ありません。
これらの定義は、テスト可能な「ブラック ボックス」配列の動作について特定の予測を行います。簡単にするために、次の関係に注目します。
配列では、配列内のすべてのアイテムのインデックス番号は、配列内のアイテム数のカウントよりも小さくなります。これはスパース配列には当てはまりますが、必須ではありません。
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 に最初のアイテムを追加した後、 内のアイテム数のカウントは 1 になると予想されますNSPointerArray
。ただし、bbums のアドバイスに従って、NSPointerArray
最初のアイテムを追加した後の のアイテム数は であり18
、 ではありません1
。
QED- aNSPointerArray
が実際には配列であることが示され、この議論の目的のために、 a NSArray
.
さらに、bbum は次の追加コメントを作成します。
NSPointerArray は確実に穴をサポートします。
これは間違いです。配列には、その何かが「何もない」場合でも、含まれるすべての項目に何かが含まれている必要があります。これはスパース配列には当てはまりません。これは、この議論における「穴」のまさに定義です。Aは、用語のスパース配列の意味にNSPointerArray
含まれていません。holes
それは、クラスを書く上での全体的なポイントの 1 つでした。最初にカウントを設定する必要があります。
スパース配列の「カウントを設定する」ことは、おそらく無意味です。
内部実装がスパース配列であるかハッシュであるか、またはその他であるかは、実装の詳細です。
これは本当です。ただし、のドキュメントでNSPointerArray
は、アイテムの配列を実装または管理する方法については言及されていません。NSPointerArray
さらに、 「が NULL ポインタの配列を効率的に管理する」とはどこにも述べていません。
QED-bbum は、スパース配列を介してポインターを内部的に効率的に処理する、文書化されていない動作に依存しています。文書化されていない動作であるため、この動作はいつでも変更される可能性があり、. 格納されている最大のインデックス番号が十分に大きい場合 (~ 2^26) 、この動作の変更は壊滅的です。NSPointerArray
NULL
NSPointerArray
そして、実際には、1 つの大きなメモリの塊として実装されているわけではありません...
繰り返しますが、これは文書化されていない非公開の実装の詳細です。このタイプの動作に依存することは、プログラミングの実践としては非常に不適切です。