2011-01-19 7 views
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]; 
} 

कतार एक 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]; 
+2

@ जेसे, आदमी नाटक नफरत करता है, सराहना करता है। –

+0

हाहा इसकी मेरी 'मुख्य' भाषा है, इसलिए मैं सिर्फ मजाक नहीं कर रहा था। जहां तक ​​कोड ... यह उतना सुंदर दिखता है जितना कि मैं विश्वास करता हूं कि ब्लॉक का उपयोग कर सकता हूं, लेकिन वास्तव में एक विशेषज्ञ नहीं। –

+0

क्या आपके प्रोग्राम में कहीं भी '[स्वयं आकार बदलें ब्लॉक' कहा जाता है, या बस 'कतार में पुन: उपयोग करें: toView:' विधि? –

उत्तर

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 डालना है, तो आपको मुख्य थ्रेड (या कुछ कार्यात्मक रूप से समकक्ष) पर dispatch_async() वापस लेना चाहिए।

यह अभी काम कर सकता है, लेकिन यह दृढ़ता से निराशाजनक है और अपरिभाषित व्यवहार का कारण बन सकता है।

+0

यह बहुत अच्छा है, और आप अज्ञात ब्लॉक को कॉपी और रिलीज़ करके पहली विधि को भी छोटा कर सकते हैं; आपको इसे पहले घोषित करने की भी आवश्यकता नहीं है। –

+0

@itaiferber हाँ, लेकिन मुझे लगता है कि आंखों पर उनके निर्माण के हिस्से के रूप में ब्लॉक पर विधियों का आह्वान नहीं करना आसान लगता है। बस मेरी वरीयता। –

+0

यह एक शानदार जवाब है। बहुत बहुत धन्यवाद! –