2010-04-26 16 views
27

ऐसा लगता है कि कुछ तर्कों के साथ चयनकर्ता को कॉल करने का एक आसान तरीका होना चाहिए जब आपके पास एक एसईएल ऑब्जेक्ट हो। मुझे सही वाक्यविन्यास नहीं मिल रहा है।एसईएल प्रदर्शन चयनकर्ता और तर्क

-(MyClass*) init: (SEL)sel owner:(NSObject*) parent 
{ 
    int i =10; 
    [parent performSelector:sel:i ]; 
} 

उत्तर

74

NSObject दस्तावेज़ीकरण पर एक नज़र डालें।

[parent performSelector:sel withObject:[NSNumber numberWithInt:i]]; 

(ध्यान दें कि यह विधि वास्तव में NSObject protocol दस्तावेज में सूचीबद्ध है): इस मामले में। चूंकि -[NSObject performSelector:withObject:] एक वस्तु तर्क की आवश्यकता है, आप की तरह

-(void)myMethodForNumber:(NSNumber*)number { 
    [self myMethod:[number intValue]]; 
} 

NSNumber Unbox करने के लिए माता-पिता की कक्षा में एक आवरण लिखने के लिए होगा।

तुम सच में एक विधि है कि गैर वस्तु तर्क सीधे लेता आह्वान करने के लिए चाहते हैं (उदाहरण के लिए, आप कॉल प्राप्त करने वाला स्रोत का नियंत्रण नहीं है और एक वर्ग को जोड़ने के लिए नहीं करना चाहते हैं), तो आपको NSInvocation उपयोग कर सकते हैं:

NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[parent methodSignatureForSelector:sel]]; 
[inv setSelector:sel]; 
[inv setTarget:parent]; 
[inv setArgument:&i atIndex:2]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation 
[inv invoke]; 

एक तरफ ध्यान दें, आपकी विधि init विधि की तरह दिखती है, लेकिन उद्देश्य-सी के लिए सही प्रारंभकर्ता पैटर्न का पालन नहीं करती है। आपको सुपर-क्लास प्रारंभकर्ता को कॉल करने की आवश्यकता है, और आपको उस कॉल से nil परिणाम के लिए परीक्षण करने की आवश्यकता है और आपको प्रारंभकर्ता विधि से स्वयं को वापस करना होगा।

-(id)myInitMethod { 
    self = [super init]; 
    if(self != nil) { 
     //perform initialization of self 
    } 

    return self; 
} 

आपका पद्धति (यदि यह एक init विधि है) तो ऐसा दिखाई देगा:: सभी मामलों में, अपने ऑब्जेक्टिव-सी प्रारंभकर्ता तरीकों की तरह दिखना चाहिए

-(id) init: (SEL)sel owner:(NSObject*) parent 
{ 
    self = [super init]; 
    if(self != nil) { 
     int i = 10; 
     NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[parent methodSignatureForSelector:sel]]; 
     [inv setSelector:sel]; 
     [inv setTarget:parent]; 
     [inv setArgument:&i atIndex:2]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation 
     [inv invoke]; 
    } 

    return self; 
} 

शैलीगत अधिक ऑब्जेक्टिव-सी होने के लिए, मैं शुरुआती -(id)initWithSelector:owner: का नाम बदलूंगा।

+0

धन्यवाद, यह ऊपर और परे चला जाता है। मैंने अनुमान लगाया था कि मुझे एनएसआईएनवोकेशन का उपयोग करने की आवश्यकता हो सकती है लेकिन यह सुनिश्चित नहीं था। बहुत बढ़िया जवाब। – madmik3

+0

एक तरफ के रूप में, भले ही आपके पास कैली पर नियंत्रण न हो, फिर भी आप उस वर्ग पर किसी श्रेणी का उपयोग करके एक रैपर विधि लिख सकते हैं ताकि ऑब्जेक्ट को आदिम प्रकार में अनबॉक्स कर सकें। –

+0

अच्छा बिंदु, एड। –

1

तरीकों कि तर्क के रूप में प्रकार id के एक या दो वस्तुओं लेने के लिए, आप उपयोग कर सकते हैं:

[parent performSelector:sel withObject:argument1]; 

या

[parent performSelector:sel withObject:argument1 withObject:argument2]; 

अन्य तर्क प्रकार के साथ तरीकों के लिए, एक NSInvocation बनाने जो मनमानी विधि कॉल को समाहित कर सकता है।

+0

सटीक विधि हस्ताक्षर को मापना सुनिश्चित करें उदा। NSSelectorFromFromString (methodWithArg1: arg2 :) – stephen

2

आप performSelector:withObject: का उपयोग करना चाहते हैं मुश्किल हिस्सा int को एनएसओब्जेक्ट में परिवर्तित कर रहा है। आप performSelector का उपयोग उन संदेशों के साथ नहीं कर सकते हैं जो int पैराम लेते हैं, इसके बजाय इसे id लेना चाहिए।

NSObject Protocol Reference से:

aSelector एक विधि है कि प्रकार आईडी की एक एकल तर्क लेता पहचान करनी चाहिए। अन्य तर्क प्रकारों और वापसी मानों के साथ विधियों के लिए, NSInvocation का उपयोग करें।

एक बार है कि परिवर्तन किया जाता है, तो आप कर सकते हैं:

id arg = [NSNumber numberWithInt:10];  
[parent performSelector:sel withObject:arg]; 
1

आप उपयोग कर सकते हैं:

- (id)performSelector:(SEL)aSelector withObject:(id)anObject 
- (id)performSelector:(SEL)aSelector withObject:(id)anObject withObject:(id)anotherObject 

या अधिक जटिल विधि उपयोग NSInvocation वर्ग का उपयोग करने के लिए यदि आप जरूरत

11

बैरी वार्क ने क्या कहा है .. मैंने आलसी प्रोग्रामर

के लिए चर्चा में अभी संशोधन किया है
-(void)myMethodWith:(int)number andBOOL:(BOOL) someBool andStr:(NSString *)str{ 
    NSLog(@"%d %d %@",number,someBool,str); 
} 

-(void) testMethod{ 
    SEL sel = @selector(myMethodWith:andBOOL:andStr:); 
    int i = 10; 
    BOOL bol = YES; 
    NSString *str = @"hey baby !"; 
    NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:sel]]; 
    [inv setSelector:sel]; 
    [inv setTarget:self]; 
    [inv setArgument:&i atIndex:2]; //arguments 0 and 1 are self and _cmd respectively, automatically set by NSInvocation 
    [inv setArgument:&bol atIndex:3]; 
    [inv setArgument:&str atIndex:4]; 
    [inv invoke]; 
} 
संबंधित मुद्दे