Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Concurrent map for NSArray
- (NSArray *)mapWithOptions:(NSEnumerationOptions)options usingBlock:(id (^)(id obj))block {
NSUInteger count = [self count];
NSArray *result = nil;
if (options & NSEnumerationConcurrent) {
volatile id * restrict objects = malloc(sizeof(id) * count);
if (!objects) {
return nil;
}
@onExit {
free((void *)objects);
};
[self enumerateObjectsWithOptions:options usingBlock:^(id obj, NSUInteger index, BOOL *stop){
obj = block(obj);
if (!obj)
obj = [EXTNil null];
if (options & NSEnumerationReverse)
index = count - index - 1;
// retain each object, in case a concurrent autorelease pool drain
// would screw us up below
objects[index] = [obj retain];
}];
@onExit {
// balance the -retain calls from within the block
for (NSUInteger i = 0;i < count;++i)
[objects[i] release];
};
// force a consistent view of the 'objects' array
OSMemoryBarrier();
// discard 'volatile' on these next two operations
result = [[self class] arrayWithObjects:(const id *)objects count:count];
} else {
id * restrict objects = malloc(sizeof(id) * count);
if (!objects) {
return nil;
}
@onExit {
free(objects);
};
[self enumerateObjectsWithOptions:options usingBlock:^(id obj, NSUInteger index, BOOL *stop){
obj = block(obj);
if (!obj)
obj = [EXTNil null];
if (options & NSEnumerationReverse)
index = count - index - 1;
objects[index] = obj;
}];
result = [[self class] arrayWithObjects:objects count:count];
}
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment