高速列挙を実装する場合、一度にすべての要素を返す必要はありません。もちろん、それらを一度に 1 つずつ返すと、高速な列挙構文しか得られず、パフォーマンス上の利点はほとんどありません。
が呼び出されるたびに 1 つの要素をcountByEnumeratingWithState:objects:count
返すことも、すべての要素を返すことも、N 個の要素だけを返すこともできます。
たとえば、大きな木があるとします。渡されたスタック バッファとその長さを使用できます。
NSUInteger numItemsToReturn = MIN(100, lengthOfStackBuffer);
numItemsToReturn
次に、ツリーの最後まで、またはツリーの最後に到達するまで、ツリーのトラバーサルを続けることができます。
内部インフラストラクチャは countByEnumeratingWithState:objects:count
、適切な数の要素を「確認」するまで呼び出しを続けます。
ただし、データの一部のみを返す場合はstate
、次に再開する場所がわかるように、 に情報を保存する必要があることに注意してください。それextra
がそのためです。
編集
元の投稿に対するコメントを見ました...高速列挙をサポートしたい場合は、上記のように非常に簡単です。
ただし、ツリーをたどって何かをしたいだけの場合は、列挙 API を検討することをお勧めします。例えば:
-(void)enumerateWithOptions:(MyTreeEnumerationOptions)options
usingBlock:^(id object, unsigned int level, BOOL isLeaf, BOOL *stop)block {
// In here, you can use the options to determine if you are doing
// pre/post depth first search, breadth-first, reverse, even concurrent.
// You also provide an easy way to communicate to the caller not only the
// object at this node, but the tree-depth of this node, whether it is a
// leaf, and anything else you want to communicate.
}
その後、ユーザーは次を呼び出すことができます。
[tree enumerateWithOptions:PreOrderDepthFirst
usingBlock:^(id object, unsigned int level, BOOL isLeaf, BOOL *stop) {
// Execute whatever code you want with this object...
// Set *stop = YES to abort the enumeration.
}];