jueves, 12 de abril de 2012

Evitar que métodos que consumen mucho tiempo se ejecuten en el hilo principal

Si tenemos un método que pide y trae algo de la web, por ejemplo una imagen, sabemos que va a tardar mucho tiempo (unos segundos). Lo que conviene es crear una queue (una cola) para que esto corra en un hilo separado y no en el hilo principal que es donde se esta ejecutando la interfaz del usuario (UIKit queue).
Para esto usamos la API GCD (Grand Central Dispatch).
Este es un ejemplo de como hacerlo:

Este es el método sin crear una queue 

-(void) viewWillAppear:(BOOL)animated
{
    NSData  *imageData = [NSData dataWithContentsOfURL:networkURL]; 
    UIImage *image = [UIImage imageWithData:imageData];
    self.imageView.image = image;
    self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.heigh);
    self.scrollView.contentSize = image.size;
} 

Este es el método con la queue 

-(void) viewWillAppear:(BOOL)animated
{
    // Creo la queue
    dispatch_queue_t downloadQueue = dispatch_queue_create("image downloader", NULL);
    dispatch_async(downloadQueue, ^{
        
        NSData  *imageData = [NSData dataWithContentsOfURL:networkURL]; 
        
        //Llamadas al UIKit en el queue principal
        dispatch_async(dispatch_get_main_queue(), ^{
            UIImage *image = [UIImage imageWithData:imageData];
            self.imageView.image = image;
            self.imageView.frame = CGRectMake(0, 0, image.size.width, image.size.heigh);
            self.scrollView.contentSize = image.size;

        });
    });

    // Cuando no existan más bloques release
    dispatch_release(downloadQueue);
}