2011-01-19 15 views
5

Estoy anidando bloques, y se ve UGGGGLY. ¿Hay alguna manera de escribir esto menos feo? Principalmente buscando sugerencias de sintaxis, en lugar de estructurales, pero aceptaré cualquiera de las dos.Sintaxis/formato al anidar bloques object-c

Mi método de bloques fábrica,

-(NSImage *(^)(CGFloat size, BOOL preview))resizeBlock { 

return (NSImage *(^)(CGFloat size, BOOL preview))[[^(CGFloat size, BOOL preview){ 
     // image-resizing code 
     return [[[NSImage alloc] init] autorelease]; 
    } copy] autorelease]; 

} 

¿Qué se llama desde un número de funciones similares a esta,

-(void)queueResize:(CGFloat)targetSize toView:(NSImageView *)targetView { 
    NSImage*(^sizeBlock)(CGFloat,BOOL) = [self resizeBlock]; 
    NSBlockOperation *bo = [NSBlockOperation blockOperationWithBlock:^(void) { 
     NSImage *previewImage = (NSImage*)sizeBlock(targetSize,YES); 
     targetView.image = previewImage; 
    }]; 
    [queue addOperation:bo]; 
} 

cola es un objeto NSOperationQueue. No compilará sin todo el lanzamiento (feo feo). Amidoinitrito?

Editar: De acuerdo con la respuesta de Dave DeLong, y http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/, he cambiado la línea

targetView.image = previewImage; 

a ser,

[targetView performSelectorOnMainThread:@selector(setImage:) withObject:previewImage waitUntilDone:YES]; 
+2

@Jesse, hombre no playa odio, aprecio. –

+0

Haha es mi idioma "principal", así que no odiaba bromear. En cuanto al código ... se ve tan lindo como puede usando bloques, creo, pero no es realmente un experto. –

+0

¿Está '[self resizeBlock]' llamado en cualquier otro lugar de su programa, o simplemente en el método 'queueResize: toView:'? –

Respuesta

6

Uso typedef:

typedef NSImage *(^KWResizerBlock)(CGFloat size, BOOL preview); 

Esto hace que su código convertido:

- (KWResizerBlock) resizeBlock { 
    KWResizerBlock block = ^(CGFloat size, BOOL preview){ 
    // image-resizing code 
    return [[[NSImage alloc] init] autorelease]; 
    }; 
    return [[block copy] autorelease]; 
} 

-(void)queueResize:(CGFloat)targetSize toView:(NSImageView *)targetView { 
    KWResizerBlock sizeBlock = [self resizeBlock]; 
    NSBlockOperation *bo = [NSBlockOperation blockOperationWithBlock:^{ 
    NSImage *previewImage = sizeBlock(targetSize, YES); 
    //do something with previewImage 
    }]; 
    [queue addOperation:bo]; 
} 

Una palabra de precaución:

Su NSBlockOperation se va a ejecutar en un hilo que no es el hilo principal, y así no es seguro de manipular cualquier elemento de interfaz de usuario desde dentro de ese contexto. Si necesita poner el previewImage en la interfaz de usuario, entonces debe dispatch_async() volver al hilo principal (o algo funcionalmente equivalente).

Puede funcionar en este momento, pero es fuertemente desalentar y puede conducir a un comportamiento indefinido.

+0

Esto es genial, e incluso puede acortar el primer método copiando y soltando un bloque anónimo; ni siquiera tiene que declararlo primero. –

+0

@itaiferber, sí, pero me parece mucho más fácil a simple vista no invocar métodos en un bloque como parte de su creación. Solo mi preferencia. –

+0

Esta es una respuesta increíble. ¡Muchas gracias! –