2011-01-19 27 views
5

Tôi đang lồng khối và trông có vẻ UGGGGLY. Có cách nào để viết điều này xấu xí hơn không? Chủ yếu là tìm kiếm các đề xuất cú pháp, thay vì cấu trúc, nhưng tôi sẽ chấp nhận.Cú pháp/định dạng khi lồng khối mục tiêu-01

My phương pháp nhà máy khối,

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

} 

nào được gọi từ một số chức năng tương tự như sau,

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

hàng đợi là một đối tượng NSOperationQueue. Nó sẽ không biên dịch mà không có tất cả (xấu xí xấu xí) đúc. Amidoinitrite?

Edit: Như mỗi câu trả lời Dave DeLong, và http://www.cimgf.com/2008/02/16/cocoa-tutorial-nsoperation-and-nsoperationqueue/, tôi đã thay đổi dòng

targetView.image = previewImage; 

được,

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

@Jesse, người đàn ông không ghét ghét, đánh giá cao. –

+0

Haha ngôn ngữ 'chính' của tôi, vì vậy tôi không ghét phải nói đùa. Theo như mã ... nó trông đẹp như nó có thể sử dụng các khối tôi tin, nhưng không thực sự là một chuyên gia. –

+0

Có phải '[self resizeBlock]' được gọi là bất cứ nơi nào khác trong chương trình của bạn hay chỉ trong phương thức 'queueResize: toView:'? –

Trả lời

6

Sử dụng typedef:

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

Điều này làm cho bạn mã trở thành:

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

Một lời cảnh cáo:

bạn NSBlockOperation sẽ được thực hiện trên một sợi đó không phải là chủ đề chính, và vì vậy nó là không an toàn để thao tác bất kỳ yếu tố giao diện người dùng từ bên trong bối cảnh đó. Nếu bạn cần đặt số previewImage vào giao diện người dùng, thì bạn nên dispatch_async() quay lại luồng chính (hoặc chức năng tương đương).

Nó có thể hoạt động ngay bây giờ, nhưng nó là mạnh không khuyến khích và có thể dẫn đến hành vi không xác định.

+0

Điều này thật tuyệt vời và bạn thậm chí có thể rút ngắn phương thức đầu tiên bằng cách sao chép và phát hành một khối ẩn danh; bạn thậm chí không phải khai báo nó trước. –

+0

@itaiferber yeah, nhưng tôi thấy nó dễ dàng hơn nhiều trong mắt để không gọi các phương thức trên một khối như là một phần của sự sáng tạo của chúng. Chỉ là sở thích của tôi. –

+0

Đây là một câu trả lời tuyệt vời. Cám ơn rất nhiều! –

Các vấn đề liên quan