gcc: Fast enumeration protocol
1
1 8.9.4 Fast Enumeration Protocol
1 -------------------------------
1
1 If you want your own collection object to be usable with fast
1 enumeration, you need to have it implement the method
1
1 - (unsigned long) countByEnumeratingWithState: (NSFastEnumerationState *)state
1 objects: (id *)objects
1 count: (unsigned long)len;
1
1 where 'NSFastEnumerationState' must be defined in your code as follows:
1
1 typedef struct
1 {
1 unsigned long state;
1 id *itemsPtr;
1 unsigned long *mutationsPtr;
1 unsigned long extra[5];
1 } NSFastEnumerationState;
1
1 If no 'NSFastEnumerationState' is defined in your code, the compiler
1 will automatically replace 'NSFastEnumerationState *' with 'struct
1 __objcFastEnumerationState *', where that type is silently defined by
1 the compiler in an identical way. This can be confusing and we
1 recommend that you define 'NSFastEnumerationState' (as shown above)
1 instead.
1
1 The method is called repeatedly during a fast enumeration to retrieve
1 batches of objects. Each invocation of the method should retrieve the
1 next batch of objects.
1
1 The return value of the method is the number of objects in the current
1 batch; this should not exceed 'len', which is the maximum size of a
1 batch as requested by the caller. The batch itself is returned in the
1 'itemsPtr' field of the 'NSFastEnumerationState' struct.
1
1 To help with returning the objects, the 'objects' array is a C array
1 preallocated by the caller (on the stack) of size 'len'. In many cases
1 you can put the objects you want to return in that 'objects' array, then
1 do 'itemsPtr = objects'. But you don't have to; if your collection
1 already has the objects to return in some form of C array, it could
1 return them from there instead.
1
1 The 'state' and 'extra' fields of the 'NSFastEnumerationState'
1 structure allows your collection object to keep track of the state of
1 the enumeration. In a simple array implementation, 'state' may keep
1 track of the index of the last object that was returned, and 'extra' may
1 be unused.
1
1 The 'mutationsPtr' field of the 'NSFastEnumerationState' is used to
1 keep track of mutations. It should point to a number; before working on
1 each object, the fast enumeration loop will check that this number has
1 not changed. If it has, a mutation has happened and the fast
1 enumeration will abort. So, 'mutationsPtr' could be set to point to
1 some sort of version number of your collection, which is increased by
1 one every time there is a change (for example when an object is added or
1 removed). Or, if you are content with less strict mutation checks, it
1 could point to the number of objects in your collection or some other
1 value that can be checked to perform an approximate check that the
1 collection has not been mutated.
1
1 Finally, note how we declared the 'len' argument and the return value
1 to be of type 'unsigned long'. They could also be declared to be of
1 type 'unsigned int' and everything would still work.
1