Question

I'm nesting blocks, and it looks UGGGGLY. Is there a way to write this less ugly? Mostly looking for syntax suggestions, rather than structural, but I'll accept either.

My block factory method,

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

}

Which is called from a number of functions similar to this,

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

queue is an NSOperationQueue object. It won't compile without all the (ugly ugly) casting. Amidoinitrite?

Edit: As per Dave DeLong's answer, and http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/, I changed the line

targetView.image = previewImage;

to be,

[targetView performSelectorOnMainThread:@selector(setImage:) withObject:previewImage waitUntilDone:YES];
Was it helpful?

Solution

Use typedef:

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

This makes your code become:

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

One word of caution:

Your NSBlockOperation is going to be executing on a thread that's not the main thread, and so it is unsafe to manipulate any UI element from within that context. If you need to put the previewImage onto the UI, then you should dispatch_async() back to the main thread (or something functionally equivalent).

It may work right now, but it is strongly discourage and can lead to undefined behavior.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top