Dispatch_async and its cousins have been around for a while, and make a bunch of async operations a whole lot easier.
I have been looking for a nice easy way to perform operations in batches; dispatch_group_notify is nice, but you have no control over the batch size.
Here’s a simple way to batch updates to a mutable array of NSManagedObjects (useful when you want to do some action requiring network connectivity to each one).
Anyway – here it is:
-(void)performAction:(void(^)(NSManagedObject*item))action inContext:(NSManagedObjectContext*)temporaryContext withItemsInArray:(NSMutableArray*)arrayOfItems usingBatchSizeOf:(NSUInteger)batchSize then:(void(^)(void))finished; { // if no items left, return if([arrayOfItems count] == 0){ finished(); return; } // take first items NSMutableArray *itemsToOperateOn; NSMutableArray *leftOvers; if([arrayOfItems count] < batchSize){ itemsToOperateOn = [arrayOfItems copy]; leftOvers = [NSMutableArray new]; }else{ itemsToOperateOn = [[arrayOfItems subarrayWithRange:NSMakeRange(0, batchSize)] mutableCopy]; leftOvers = [[arrayOfItems subarrayWithRange:NSMakeRange(batchSize, [arrayOfItems count] - batchSize)] mutableCopy]; } dispatch_group_t actionGroup = dispatch_group_create(); for(NSManagedObject *itemToOperateOn in itemsToOperateOn) { dispatch_group_async(actionGroup, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ action(itemToOperateOn); }); } // notify when done dispatch_group_notify(actionGroup, dispatch_get_main_queue(), ^{ NSLog(@" - Batch Operation performed, %i left", [leftOvers count]); [temporaryContext save:nil]; [self performAction:action inContext:temporaryContext withItemsInArray:leftOvers usingBatchSizeOf:batchSize then:finished]; }); }