2009-10-18 5 views
5

चलो कहते हैं कि मैं इस हस्ताक्षर के साथ एक विधि करते हैं:performSelector उपयोग कैसे करें: withObject: afterDelay: कई तर्क के साथ एक विधि पर

-(void)plotPoly:(Polygon *)poly WithColor:(UIColor *)color AndFill:(BOOL)filled; 

मैं कैसे मिलता है कि वहाँ के रूप में में UIColor और BOOL अच्छी तरह से पॉलीगॉन?

क्या मुझे उन्हें NSArray में लपेटना चाहिए और उन्हें बुलाए गए विधि के अंदर खींचें? इसका मतलब यह होगा कि मुझे विधि सिग बदलना है, है ना?

क्या ऐसा करने के लिए एक और शानदार तरीका है?

+0

क्या हमें यूआईसीओएलर से लगता है कि आप आईफोन पर हैं? – nall

+0

मैं हूं। क्या इससे कुछ अन्तर पड़ता है? – willc2

+1

हां - यदि आप हिम तेंदुए पर थे, तो आप इसे हल करने के लिए ब्लॉक का उपयोग कर सकते हैं। – bbum

उत्तर

7

मैंने कुछ सप्ताह पहले एक समान प्रश्न का उत्तर दिया था। इस प्रश्न के लिए संपादित नीचे दिए गए उत्तर।

सामान्य रूप से, मैं इस तरह के काम के लिए NSInvocation से बचता हूं। यह एक रखरखाव सिरदर्द होता है और, विशेष रूप से, भविष्य में refactoring में कठिनाई पैदा करता है।

सबसे पहले, इस विधि दिया:

-(void)plotPoly:(Polygon *)aPoly color:(UIColor *)aColor filled:(BOOL)filledFlag; 

यह नामकरण सम्मेलनों में थोड़ा और अधिक बारीकी से इस प्रकार है:

-(void)plotPoly:(Polygon *)poly WithColor:(UIColor *)color AndFill:(BOOL)filled; 

यह आम तौर पर के रूप में घोषित किया जाएगा।

अब, मैं वास्तव में एक साधारण वर्ग में तर्कों को कैप्चर करता हूं जो -invoke विधि प्रदान करता है। इस तरह की एक इंटरफेस के साथ

कुछ:

PolyPlotter.h:

@interface PolyPlotter : NSObject 
{ 
    Polygon *poly; 
    UIColor *color; 
    BOOL filled; 
} 

+ plotterWithPoly: (Polygon *) aPoly color: (UIColor *) aColor filled: (BOOL) filledFlag; 

- (void) plot; 
@end 

PolyPlotter.m:

@interface PolyPlotter() 
@property Polygon *poly; 
@property UIColor *color; 
@property BOOL filled; 
@end 

@implementation PolyPlotter 
@synthesize poly, color, filled; 

+ plotterWithPoly: (Polygon *) aPoly color: (UIColor *) aColor filled: (BOOL) filledFlag; 
{ 
    PolyPlotter *polygonPlotter = [PolyPlotter new]; 
    polygonPlotter.poly = aPoly; 
    polygonPlotter.color = aColor; 
    polygonPlotter.filled = filledFlag; 
    return [polygonPlotter autorelease]; 
} 

- (void) plot; 
{ 
    // ... do your plotting here ... 
} 
@end 

प्रयोग सरल है। बस पॉलीगॉनप्लॉटर का एक उदाहरण बनाएं और देरी के बाद या मुख्य धागे या जो भी हो, चयनकर्ता plot निष्पादित करने के लिए कहें।

प्रश्न को देखते हुए, मुझे संदेह है कि ड्राइंग के समय आपको थोड़ा अधिक संदर्भ की आवश्यकता हो सकती है? यदि हां, तो आप से, कहते हैं -plot लिए एक तर्क के रूप कि जानकारी दे सकते हैं, के रूप में विधि की घोषणा:

- (void) plot: (UIView *) aViewToPlotIn; 

या ऐसा ही कुछ।

जैसा कि मैंने कहा, थोड़ा और कोड, लेकिन एनएसआईएनवोकेशन पैटर्न की तुलना में अधिक लचीला और प्रतिक्रियाशील। उदाहरण के लिए, आप आसानी से पॉलीगॉनप्लटर कुछ ऐसा कर सकते हैं जिसे संग्रहीत किया जा सकता है।

0

मेरा मानना ​​है कि एनएसएआरएआरई एक उचित समाधान है, और हां इसका मतलब है कि एनएसएआरएआरई * को एकमात्र तर्क के रूप में लेने के लिए विधि हस्ताक्षर बदलना होगा।

4

जो हेविट के three20 पुस्तकालय है कि आप उपयोगी लग सकते performSelector के कुछ उन्नत संस्करण है (मैं केवल एक टुकड़ा पोस्ट):

- (id)performSelector:(SEL)selector withObject:(id)p1 withObject:(id)p2 withObject:(id)p3 { 
    NSMethodSignature *sig = [self methodSignatureForSelector:selector]; 
    if (sig) { 
    NSInvocation* invo = [NSInvocation invocationWithMethodSignature:sig]; 
    [invo setTarget:self]; 
    [invo setSelector:selector]; 
    [invo setArgument:&p1 atIndex:2]; 
    [invo setArgument:&p2 atIndex:3]; 
    [invo setArgument:&p3 atIndex:4]; 
    [invo invoke]; 
    if (sig.methodReturnLength) { 
     id anObject; 
     [invo getReturnValue:&anObject]; 
     return anObject; 
    } else { 
     return nil; 
    } 
    } else { 
    return nil; 
    } 
} 

बस NSObject की एक श्रेणी में शामिल करें।

Polygon *poly; 
UIColor *color; 
BOOL filled; 
// Assume the above variables exist 
NSInvocation *inv = [NSInvocation invocationWithMessageSignature:[target messageSignatureForSelector:message]]; 
[inv setArgument:&poly atIndex:2]; 
[inv setArgument:&color atIndex:3]; 
[inv setArgument:&filled atIndex:4]; 
[inv performSelector:@selector(invokeWithTarget:) withObject:target afterDelay:1]; 

अन्य सबसे अच्छा विकल्प सिर्फ एक आवरण विधि है कि मूल विधि आप कॉल बनाने के लिए है:

+0

मैं बाद में कैसे कार्यान्वित करूं: समारोह? – willc2

9

फिर भी वास्तव में क्या नहीं मैं कम छी सुरुचिपूर्ण कहेंगे, लेकिन पूरी एपीआई को बदलने के लिए की तुलना में NSInvocation है उचित तर्क (शायद एक शब्दकोश या सरणी के रूप में दिया गया) के साथ चाहते हैं, जो विलंब के बाद प्रदर्शन करने के लिए आवश्यक हस्ताक्षर से मेल खाता है।

+1

तर्क सूचकांक 3 से शुरू क्यों होता है और नहीं 2 (जैसे दस्तावेज़ इंगित करते हैं)? – willc2

+0

यह 2 से शुरू होना चाहिए, नहीं 3. –

+0

यह 2 से शुरू होता है। तर्क 0 और 1 छुपा 'स्वयं' और '_cmd' पैरामीटर के लिए आरक्षित हैं। –

संबंधित मुद्दे