5

私はブロックを入れ子にしています、そしてそれは醜いように見えます。これをそれほど醜くなく書く方法はありますか?構造的ではなく、主に構文の提案を探していますが、どちらも受け入れます。

私のブロックファクトリメソッド、

-(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 に答える