Синтаксис / форматирование при вложении блоков target-c
Я раскрою блоки, и это выглядит ужасно. Есть ли способ написать это менее уродливо? В основном ищет синтаксические предложения, а не структурные, но я приму либо.
Мой блочный фабричный метод,
-(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];
}
Очередь является объектом NSOperationQueue. Он не скомпилируется без всех (безобразно-уродливых) кастингов. Amidoinitrite?
Изменить: в соответствии с ответом Дейва Делонга и http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/, я изменил строку
targetView.image = previewImage;
быть,
[targetView performSelectorOnMainThread:@selector(setImage:) withObject:previewImage waitUntilDone:YES];
1 ответ
Использование 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
будет выполняться в потоке, который не является основным, и поэтому небезопасно манипулировать любым элементом пользовательского интерфейса из этого контекста. Если вам нужно поставить previewImage
на интерфейс, то вы должны dispatch_async()
вернуться к основному потоку (или что-то функционально эквивалентное).
Это может работать прямо сейчас, но это сильно обескураживает и может привести к неопределенному поведению.