5

我正在嵌套块,它看起来 UGGGGLY。有没有办法写这个不那么难看?主要是寻找语法建议,而不是结构性的,但我都会接受。

我的块工厂方法,

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

}

从许多与此类似的函数中调用它,

-(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 是一个 NSOperationQueue 对象。如果没有所有(丑陋的)强制转换,它将无法编译。亚硝酸胺?

编辑:根据 Dave DeLong 的回答和http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/,我改变了行

targetView.image = previewImage;

成为,

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

1 回答 1

6

使用typedef

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

这使您的代码变为:

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

一个警告:

NSBlockOperation将在不是主线程的线程上执行,因此从该上下文中操作任何 UI 元素都是不安全的。如果您需要将其previewImage放到 UI 上,那么您应该dispatch_async()回到主线程(或功能等效的东西)。

它现在可能有效,但强烈劝阻它并可能导致未定义的行为。

于 2011-01-19T22:35:29.973 回答