I just want to prerender different images for fast access. I use grand central dispatch here to execute the different blocks.
After starting the queue, I want to set the first image when its done. With the current code below, unfortunately the first image will only be displayed when all images has been rendered.
So how can i modify the code? Is it possible to get a delegate when each image has finished?
Here´s the code:
// Async prerendering
for (int i = 0; i < count; i++) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
dispatch_async(dispatch_get_main_queue(), ^{
UIImage* finalImage = [self prerenderImageForIndex:i];
[self.imageArray addObject:finalImage];
// TODO: i want to display the first image.
// rendering goes on in the background
if (i==0 && [self.imageArray objectAtIndex:0] != nil ) {
self.image = [self.imageArray objectAtIndex:0];
}
});
});
}
Update:
-(UIImage*) prerenderImageForIndex:(int)frame {
UIGraphicsBeginImageContextWithOptions(CGSizeMake(self.frame.size.width, self.frame.size.height), NO, 0);
for (int i=0; i< [configurationArray count]; i++) {
//... get the layerName
UIImage* layerImage = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:layerName ofType:@"png"]];
// draw layer with blendmode and alpha
[layerImage drawInRect:CGRectMake(x, y, layerImage.size.width, layerImage.size.height)
blendMode:layerblendmode
alpha: layeralpha];
}
// Get current context as an UIImage
UIImage* finalImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return finalImage;
}
i just want to know how do i cancel/stop or restart a running queue? Is that possible? Thanks for your help.
you have to use a serial queue, which executes FIFO for example:
dispatch_queue_t queue;
queue = dispatch_queue_create("myImageQueue", NULL);
for(int i = 0; i<count; i++) {
dispatch_async(queue, ^{
// do your stuff in the right order
});
}
for serial Dispatch queues look at: http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html
I'm not sure why you have the dispatch_async calls nested like this but maybe that's the problem. I would imagine something like below would accomplish what you want. You only need to get the main queue when you actually want to do the UI update, everything else should be done on the background queue.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
UIImage* finalImage = [self prerenderImageForIndex:i];
[self.imageArray addObject:finalImage];
if (i==0 && [self.imageArray objectAtIndex:0] != nil ) {
dispatch_async(dispatch_get_main_queue(), ^{
self.image = [self.imageArray objectAtIndex:0];
});
}
});
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With