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];
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With