Reputation: 181
I have a data structure that I wanted to enumerate. I tried to implement my object's NSFastEnumerator as follows:
- (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state
objects:(__unsafe_unretained id [])buffer
count:(NSUInteger)len {
NSUInteger c = 0;
while (c < len) {
id obj = [self objectAtIndex:state->state];
if (obj == nil) break;
buffer[c] = obj;
c++;
state->state++;
}
state->itemsPtr = buffer;
state->mutationsPtr = nil;
return c;
}
If I use objectAtIndex directly, my object works properly. I get a nil when the index doesn't exist. But when I then use the for loop:
for (Pin *pin in coll) { ... }
the code runs through the above function fine and fills in state with what appears to be valid values and returns the number of objects, then I get an EXC_BAD_ACCESS failure at the for statement itself.
What am I doing wrong in this implementation?
Upvotes: 4
Views: 413
Reputation: 5374
I just had a similar issues, and after looking more closely into Apple's FastEnumerationSample, this part (that I had overlooked) jumped at me:
// We are not tracking mutations, so we'll set state->mutationsPtr to point into one of our extra values,
// since these values are not otherwise used by the protocol.
// If your class was mutable, you may choose to use an internal variable that is updated when the class is mutated.
// state->mutationsPtr MUST NOT be NULL.
state->mutationsPtr = &state->extra[0];
The important part being: state->mutationsPtr
MUST NOT be NULL. I just used the example line provided and it worked like a charm!
Upvotes: 2
Reputation: 318
Instead of:
id obj = [self objectAtIndex:state->state];
use
__unsafe_unretained id = [self objectAtIndex:state->state];
Upvotes: 0
Reputation: 118671
I'm assuming you're using ARC. The problem may be that the buffer
is an array of __unsafe_unretained
objects, so ARC might be over-releasing them. But what does your objectAtIndex:
method look like? This shouldn't be a problem if you are returning objects that are guaranteed to be alive at least as long as your object itself.
Upvotes: 1