Az Objective-C programozási nyelv

NSFastEnumeration

Általános leírás

Ahogyan a vezérlési szerkezete foreach szekciójában már láthattuk, lehetőségünk van végigiterálni egy kollekció elemein (iOS 2.0 és későbbi verziókban).

for ( Item* item in myCollection ) { /*...*/ }

Erre az NSArray, az NSDictionary, valamint legtöbb Foundation Frameworkben definiált gyűjteményben lehetőségünk van. Ha azt szeretnénk, hogy a saját osztályunkon is lehessen ilyen módon iterálni, akkor meg kell felelnünk az NSFastEnumeration protokollnak.

NSFastEnumeration protokoll

Az NSFastEnumeration protokollt a NSEnumerator.h fájlban deklarálja a Foundation Framework az alábbi módon:

@protocol NSFastEnumeration - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len @end

A paraméterek jelentése:

NSFastEnumerationState

A fentebb látható iteráció során ilyen típusú objektumban tárolhatjuk a szükséges információkat. Az NSFastEnumerationState az alábbi módon van definiálva:

typedef struct { unsigned long state; id *itemsPtr; unsigned long *mutationsPtr; unsigned long extra[5]; } NSFastEnumerationState;

Mezők jelentése:

Példa - láncolt lista

A példában egy C típusú láncolt listát fogunk használni a műveletek megvalósításának bemutatása nélkül (ezek nyilván senkinek nem okoznak sok gondot). A iteráció során egyesével adjuk vissza az elemeket.

MyChainedListNode.h

#import <Foundation/Foundation.h> @interface MyChainedListNode : NSObject { -(id)value; -(MyChainedListNode*)next; } - (MyChainedListNode*) initWithValue: (id)val; - (id) getValue; - (void) setNext: (MyChainedListNode*)node; - (void) getNext; @end

MyChainedList.h

#import "MyChainedListNode.h" @interface MyChainedList : NSObject<NSFastEnumeration> { -(MyChainedListNode*)start; -(MyChainedListNode*)end; -(NSInteger)size; -(long)mutated; //ha valtozik a lista mutated=1 } - (MyChainedList*) init; - (NSInteger) count; - (void) add: (id) value; //... @end

MyChainedList.m

#import "MyChainedList.h @implementation MyChainedList //... -(NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len { state->itemsPtr = stackbuf; if(state->state == 0) //inicializalas { state->mutationsPtr = &mutated; state->state=1; mutated = 0; if (count>0) { extra[0] = (long)start; stackbuf[0] = [start getValue]; return 1; } else { return 0; } } if (mutated) { //dobj kivetelt, ha nem szeretned, hogy modositani lehessen a listat iteracio kozben } MyChainedListNode* node = (MyChainedListNode*)extra[0]; node = [node getNext]; if (node) { extra[0] = (long)node; stackbuf[0] = [start getValue]; return 1; } else { return 0; } } //... @end

Link

További információ megtalálható a http://developer.apple.com/library/ios/#documentation/cocoa/Reference/NSFastEnumeration_protocol/Reference/NSFastEnumeration.html oldalon angol nyelven, illetve példa található a http://developer.apple.com/library/ios/#samplecode/FastEnumerationSample/Introduction/Intro.html oldalon.