Scroll to navigation

dispatch_apply(3) Library Functions Manual dispatch_apply(3)

NAME

dispatch_apply
schedule blocks for iterative execution

SYNOPSIS

#include <dispatch/dispatch.h>
void
dispatch_apply(size_t iterations, dispatch_queue_t queue, void (^block)(size_t));
void
dispatch_apply_f(size_t iterations, dispatch_queue_t queue, void *context, void (*function)(void *, size_t));

DESCRIPTION

The dispatch_apply() function provides data-level concurrency through a "for (;;)" loop like primitive:
dispatch_queue_t the_queue = dispatch_get_concurrent_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT); 
size_t iterations = 10; 
 
// 'idx' is zero indexed, just like: 
// for (idx = 0; idx < iterations; idx++) 
 
dispatch_apply(iterations, the_queue, ^(size_t idx) { 
	printf("%zu\n", idx); 
});
Like a "for (;;)" loop, the dispatch_apply() function is synchronous. If asynchronous behavior is desired, please wrap the call to dispatch_apply() with a call to dispatch_async() against another queue.
Sometimes, when the block passed to dispatch_apply() is simple, the use of striding can tune performance. Calculating the optimal stride is best left to experimentation. Start with a stride of one and work upwards until the desired performance is achieved (perhaps using a power of two search):
#define	STRIDE	3 
 
dispatch_apply(count / STRIDE, queue, ^(size_t idx) { 
	size_t j = idx * STRIDE; 
	size_t j_stop = j + STRIDE; 
	do { 
		printf("%zu\n", j++); 
	} while (j < j_stop); 
}); 
 
size_t i; 
for (i = count - (count % STRIDE); i < count; i++) { 
	printf("%zu\n", i); 
}

FUNDAMENTALS

Conceptually, dispatch_apply() is a convenient wrapper around dispatch_async() and a semaphore to wait for completion. In practice, the dispatch library optimizes this function.
The dispatch_apply() function is a wrapper around dispatch_apply_f().

SEE ALSO

dispatch(3), dispatch_async(3), dispatch_queue_create(3), dispatch_semaphore_create(3)
May 1, 2009 Darwin