2009-05-31 14 views
51

विधि के लिए:मैं पैरामीटर के रूप में @ चयनकर्ता कैसे पास करूं?

[NSThread detachNewThreadSelector:@selector(method:) toTarget:self withObject:(id)SELECTOR]; 

मैं एक @selector में कैसे पारित करते हैं? मैंने इसे संकलित करने के लिए इसे (आईडी) पर कास्ट करने का प्रयास किया, लेकिन यह रनटाइम में दुर्घटनाग्रस्त हो गया।

+(void)method1:(SEL)selector{ 
[NSThread detachNewThreadSelector:@selector(method2:) toTarget:self withObject:selector]; 
} 

यह दुर्घटनाओं:


अधिक विशेष रूप से, मैं इस तरह एक विधि है। मैं क्रैशिंग के बिना चयनकर्ता में कैसे पास करूं, ताकि धागा तैयार होने पर नया धागा चयनकर्ता को कॉल कर सके?

उत्तर

67

समस्या यहाँ एक विधि, दर असल करने के लिए एक चयनकर्ता गुजर नहीं है, लेकिन एक चयनकर्ता जहां एक वस्तु की उम्मीद है गुजर। ऑब्जेक्ट के रूप में गैर-ऑब्जेक्ट मान को पास करने के लिए, आप NSValue का उपयोग कर सकते हैं। इस मामले में, आपको एक ऐसी विधि बनाने की आवश्यकता होगी जो NSValue स्वीकार करता है और उचित चयनकर्ता को पुनर्प्राप्त करता है। यहाँ एक उदाहरण कार्यान्वयन है:

@implementation Thing 
- (void)method:(SEL)selector { 
    // Do something 
} 

- (void)methodWithSelectorValue:(NSValue *)value { 
    SEL selector; 

    // Guard against buffer overflow 
    if (strcmp([value objCType], @encode(SEL)) == 0) { 
     [value getValue:&selector]; 
     [self method:selector]; 
    } 
} 

- (void)otherMethodShownInYourExample { 
    SEL selector = @selector(something); 
    NSValue *selectorAsValue = [NSValue valueWithBytes:&selector objCType:@encode(SEL)]; 
    [NSThread detachNewThreadSelector:@selector(methodWithSelectorValue:) toTarget:self withObject:selectorAsValue]; 
} 
@end 
+0

+50 उत्कृष्ट! मैं कभी यह याद नहीं कर सकता कि यह कैसे करें ... – bentford

+0

आपको नए धागे के साथ ऐसा क्यों करना है? – cstack

+2

@cstack: यदि आप सवाल देखते हैं, तो एक नया धागा पैदा करने वाला वह ओपी क्या करने की कोशिश कर रहा था। तो मैंने अपने उदाहरण में एक ही काम किया। लेकिन यह तकनीक किसी भी नए धागे को बढ़ाने के लिए विशिष्ट नहीं है। – Chuck

0

आप एक वस्तु निर्दिष्ट नहीं करना चाहते हैं, बस नहीं के बराबर का उपयोग करें।

[NSThread detachNewThreadSelector:@selector(method:) toTarget:self withObject:nil]; 

यदि आपको चयनकर्ता को ऑब्जेक्ट पास करने की आवश्यकता है तो यह ऐसा कुछ दिखाई देगा।

यहां मैं "setText" विधि को एक स्ट्रिंग पास कर रहा हूं।

NSString *string = @"hello world!"; 
[NSThread detachNewThreadSelector:@selector(setText:) toTarget:self withObject:string]; 


-(void)setText:(NSString *)string { 
    [UITextField setText:string]; 
} 
+0

कृपया अपडेट किए गए प्रश्न देखें। धन्यवाद! – erotsppa

4

उपयोग NSValue, इसलिए जैसे:

+(void)method1:(SEL)selector { 
    NSValue *selectorValue = [NSValue value:&selector withObjCType:@encode(SEL)]; 
    [NSThread detachNewThreadSelector:@selector(method2:) 
          toTarget:self 
          withObject:selectorValue]; 
} 

NSValue मनमाने ढंग से गैर-वस्तु प्रकार के लिए एक वस्तु-आवरण के रूप में करना है।

+0

मेरा मानना ​​है कि आप "चयनकर्ता" से पहले एक "&" चिह्न खो रहे हैं ताकि यह "... मूल्य: चयनकर्ता ..." के बजाय "... मान: और चयनकर्ता ..." हो। – Senseful

+0

सच है। ध्यान देने के लिए धन्यवाद; मैंने इसे ठीक कर दिया है। –

41

आप NSStringFromSelector() और NSSelectorFromString() फ़ंक्शंस का उपयोग कर चयनकर्ताओं और स्ट्रिंग ऑब्जेक्ट्स के बीच कनवर्ट कर सकते हैं। तो आप इसके बजाय स्ट्रिंग ऑब्जेक्ट्स पास कर सकते हैं।

वैकल्पिक रूप से, यदि आप अपनी विधियों को नहीं बदलना चाहते हैं, तो आप अपनी विधि कॉल के लिए आमंत्रण बनाने के लिए NSInvocation बना सकते हैं (क्योंकि यह गैर-ऑब्जेक्ट तर्कों के साथ आमंत्रण स्थापित कर सकता है), और फिर इसे कॉल करने के लिए [NSThread detachNewThreadSelector:@selector(invoke) toTarget:myInvocation withObject:nil];

+0

इसे और अधिक अपवॉट की आवश्यकता है –

+0

यह बहुत अच्छा जवाब है, इच्छा है कि मैं इसे और अधिक लोगों को ऊपर उठाने के लिए प्राप्त कर सकूं। –

+0

बहुत धन्यवाद, यह वही था जो मुझे चाहिए था। – amergin

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

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