Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Syntax/formatting when nesting objective-c blocks

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];
like image 392
Kenny Winker Avatar asked Jan 19 '11 21:01

Kenny Winker


1 Answers

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.

like image 158
Dave DeLong Avatar answered Oct 23 '22 11:10

Dave DeLong