Here's a framework to start with. The code assumes that the output view is a UIImageView. The background task uses a bitmapped memory context to create a new image for the output view. When the background drawing task completes, the main thread assigns the resulting image to the UIImageView.
The sequenceNumber is used to discard images that are out of date before they finish being drawn. One possible problem is that events arrive so quickly that every image is out of date before being finished. Solving that problem is left as an exercise for the reader.
@interface SomeClass()
@property (weak, nonatomic) IBOutlet UIImageView *someView;
@property (nonatomic) int64_t sequenceNumber;
@end
@implementation SomeClass
- (UIImage *)createImageUsingBitmapMemoryContextOfSize:(CGSize)size
{
// create the memory bitmap context
UIGraphicsBeginImageContext( size );
CGContextRef context = UIGraphicsGetCurrentContext();
// draw something
[[UIColor blueColor] set];
CGContextFillEllipseInRect( context, CGRectMake(0, 0, size.width, size.height) );
// create a UIImage
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// return the image
return( result );
}
// Note: the following function should only be called on the main thread
- (void)updateInResponseToSomeEvent
{
self.sequenceNumber++;
int64_t sequenceNumber = self.sequenceNumber;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^
{
UIImage *image = [self createImageUsingBitmapMemoryContextOfSize:self.someView.bounds.size];
dispatch_async( dispatch_get_main_queue(), ^
{
if ( sequenceNumber == self.sequenceNumber )
self.someView.image = image;
});
});
}