2012-05-04 45 views
5

我只是想预渲染不同的图像以便快速访问。 我在这里使用大中央调度执行不同的块。Grand Central Dispatch - 在加载时显示第一张图片?

启动队列后,我想在完成后设置第一个图像。 使用下面的当前代码,不幸的是,第一个图像将只显示所有图像已被渲染。

那么我如何修改代码?每张图片完成后是否有可能获得委托?

Here's代码:

// 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]; 
       } 
      }); 
     }); 
    } 

更新:

-(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; 

} 

我只是想知道如何取消/停止或重新启动正在运行的队列? 这可能吗? 感谢您的帮助。

回答

2

你必须使用一个串行队列,从而例如执行FIFO:

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 
    }); 
} 

串行调度队列查看: http://developer.apple.com/library/ios/#documentation/General/Conceptual/ConcurrencyProgrammingGuide/OperationQueues/OperationQueues.html

+0

是的,这就解决了问题!非常感谢你。我在“dispatch_async(queue,^ {”)中分配了“self.image”,现在它工作的很完美,不过我会看看关于这个的文档,再次感谢。 – geforce

2

我不知道为什么你有dispatch_async调用嵌套像这样,但也许这就是问题所在。我会想象下面的东西会达到你想要的。您只需要在实际想要执行UI更新时获取主队列,其他所有内容都应在后台队列上完成。

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]; 
     }); 
    } 
}); 
+0

感谢史蒂夫,但从来就已经测试。当我这样做时,我的所有图像将随机呈现:)但我只需要按照正确的索引顺序逐个呈现图像并显示第一个图像...任何其他想法? – geforce

+0

嗯,所以我现在有点困惑。我以为你只想显示第一张图像,并让所有其他图像加载到背景中。我假设你的[self prerenderImageForIndex:i]方法正在进行一些网络调用来获取图像。也许你可以发布该方法,让我更好地理解整个画面。 – SteveB

+0

谢谢史蒂夫,我刚刚添加了“prerenderImageForIndex”方法。希望有帮助... – geforce

相关问题