私はクラスを持っており、クラスが NSFastEnumeration プロトコルに準拠していることを確認したいと考えています。ドキュメントを読みましたが、よくわかりません。プロトコルメソッドが何を返すべきか、またそれがどのように機能するか教えてもらえますか?
2 に答える
Apple のFastEnumerationSampleは何をすべきかを示していますが、ここでは内訳を示します。
唯一のNSFastEnumeration
メソッドcountByEnumeratingWithState:objects:count:
は、コレクションのチャンクを返します。0 を返すことによってそれ以上の項目がないことを示すまで、さらに項目が必要になるたびに実行されます。チャンクはid
s の C 配列として渡されます。
メソッド内で、state
パラメーターは、使用するデータのほとんど (すべてではないにしても) を保持します。を個別に呼び出すたびに設定state->itemsPtr
および更新する必要があります。の各フィールドの簡単な説明は次のとおりです。state->state
countByEnumeratingWithState:objects:count:
NSFastEnumerationState
state
: 反復されるシーケンス内の位置を表します。インデックス付きコレクションの場合、これがインデックスになります。リンクされたリストの場合、これはノード ポインターである可能性があります。他の型の場合、これはより複雑な型になる可能性があります (たとえば、ツリーの場合、state->state
ノードを格納するスタックとして使用される NSMutableArray になる可能性があります)。countByEnumeratingWithState:objects:count:
が最初に呼び出されたときstate->state
は 0 です。この条件をチェックしてstate
構造体を初期化します。itemsPtr
: チャンク内のアイテム。s のC 配列を指しid
ます。Cocoa はこの配列をループし、各項目を for-in ループで指定された変数に順番にバインドします。mutationsPtr
: 変更可能なコレクションの場合、 への最後の呼び出し以降にコレクションが変更されたことを示すために使用されますcountByEnumeratingWithState:objects:count:
。通常、状態を初期化するときにこれを 1 回設定します。コレクション ミューテーターは、this が指す値をインクリメントします。Cocoa は、によって返されcountByEnumeratingWithState:objects:count:
た値を前回の呼び出しからの値と比較します。それらが異なる場合、Cocoa は例外をスローします。extra
: これを使用して、追加のデータを保存できます。
state->state
の任意の要素を好きなように設定できstate->extra
ます。これらは便宜上のみ提供されており、Cocoa には影響しません。state->itemsPtr
ただし、*state->mutationsPtr
メソッドによって返される値は Cocoa に影響します。
他の 2 つのメソッド パラメータについてstackbuf
は、項目を保持するために Cocoa が提供する配列です。その使用はオプションですが、使用しない場合は、state->itemPtr
. 使用する場合は、呼び出しごとに設定state->itemsPtr
します。は の長さで、その中に収納できるアイテムの最大数です。stackbuf
len
stackbuf
参考文献:
- Friday Q&A 2010-04-16: 高速列挙の実装(mikeash.com)
- countByEnumratingWithState:objects:count: の実装(Cocoa with Love)
- NSFastEnumeration プロトコル リファレンス
- カスタム クラス(SO)に NSFastEnumerator を実装する
優れた説明を見つけた後、このスレッドを復活させます。Apple リンクが壊れているようです。ここで試すことができます: https://developer.apple.com/library/ios/#samplecode/FastEnumerationSample/Introduction/Intro.html
私が見つけた高速列挙を実装するための最良の例は、http://mikeash.com/pyblog/friday-qa-2010-04-16-implementing-fast-enumeration.htmlです。それはそれよりもはるかに悪いように見えます。