Re: Implementing NSFastEnumeration
Gerd Knops <[email protected]>
| Newsgroups | gmane.comp.macosx.devel |
|---|---|
| Message-ID | <[email protected]> |
On Oct 1, 2009, at 8:13 AM, Christiaan Hofman wrote:
> I've been reading the documentation on NSFastEnumeration (both the
> docs on the protocol and the section in the Objective-C 2.0
> Programming Language guide). But it is really cryptic and misses
> most of the relevant information to help in implementing it.
Below some code I have been using. To access the array to be
enumerated, it uses these methods that my code provides:
- (unsigned)version;
- (unsigned)countOfChildrenAtVersion:(unsigned)aVersion;
- (id)childAtIndex:(unsigned)index forVersion:(unsigned)aVersion;
It makes use of the extra array to keep track of the version it is
enumerating, in case it changes while the enumeration goes on. In my
case it is safe to use "self" as the mutationsPtr because the only way
the child array might change is by adding additional children.
Looking at it now I am not sure if the [child retain] part is correct,
might create a memory leak. I'll have to check on that. And it'll need
some changes to be 64-bit safe.
But anyway this should get you started.
Gerd
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)
state
objects:(id *)stackbuf
count:(NSUInteger)len
{
// typedef struct {
// unsigned long state;
// id *itemsPtr;
// unsigned long *mutationsPtr;
// unsigned long extra[5];
// } NSFastEnumerationState;
unsigned idx=state->state;
unsigned version=(idx>0)?state->extra[0]:[self version];
unsigned numChildren=[self countOfChildrenAtVersion:version];
NSUInteger now=0;
while(now<len && idx<numChildren)
{
id child=[self childAtIndex:idx forVersion:version];
stackbuf[now++]=[child retain];
idx++;
}
state->extra[0]=version;
state->state=(unsigned long)idx;
state->itemsPtr=stackbuf;
state->mutationsPtr=(unsigned long *)self;
return now;
}