2008-09-22 10 views
89

मुझे पता है कि @selector(MyMethodName:) का उपयोग कर संकलन समय पर SEL कैसे बनाएं, लेकिन मैं जो करना चाहता हूं वह NSString से गतिशील रूप से चयनकर्ता बना सकता है। क्या यह भी संभव है?मैं उद्देश्य-सी के साथ रनटाइम पर गतिशील रूप से चयनकर्ता कैसे बना सकता हूं?

मैं क्या कर सकता:

SEL selector = @selector(doWork:); 
[myobj respondsToSelector:selector]; 

मैं आपकी क्या अपेक्षाएं हैं: (छद्म कोड, इस स्पष्ट रूप से काम नहीं करता है)

SEL selector = selectorFromString(@"doWork"); 
[myobj respondsToSelector:selector]; 

मैं एप्पल एपीआई डॉक्स खोज कर रहा है, लेकिन ऐसा कोई तरीका नहीं मिला है जो संकलन-समय @selector(myTarget:) वाक्यविन्यास पर निर्भर नहीं है।

उत्तर

175

मैं एक उद्देश्य-सी प्रोग्रामर नहीं हूं, केवल एक सहानुभूतिकर्ता हूं, लेकिन शायद NSSelectorFromString आपको चाहिए। इसने Runtime Reference में स्पष्टीकरण का उल्लेख किया है जिसका उपयोग आप एक चयनकर्ता को स्ट्रिंग को कन्वर्ट करने के लिए कर सकते हैं।

+5

मैं अपने Google फू पर ब्रश की जरूरत है। यह वही है जो मैं चाहता था (या ऐसा नहीं था) की तलाश में था। – craigb

+0

ठीक है, मेरे पास अभी भी मेरे बुकमार्क्स में उड़ान भरने के लिंक थे क्योंकि मैंने कुछ दिन पहले उद्देश्य-सी 2.0 दस्तावेज़ों के माध्यम से पढ़ा है। –

40

एक्सकोड दस्तावेज़ के अनुसार, आपका psuedocode मूल रूप से इसे सही बनाता है।

@selector() निर्देश के साथ संकलन समय पर एसईएल चर के मानों को असाइन करना सबसे कुशल है। हालांकि, कुछ मामलों में, किसी प्रोग्राम को रनटाइम पर किसी वर्णक को किसी वर्णक को कनवर्ट करने की आवश्यकता हो सकती है। यह NSSelectorFromString समारोह के साथ किया जा सकता है:

setWidthHeight = NSSelectorFromString(aBuffer);

संपादित करें: क्षमा, बहुत धीमी गति से। : पी

+2

'NSStringFromSelector (@" doWork ") 'इसे दूसरे तरीके से परिवर्तित करता है (केवल fyi) – bendytree

+8

मुझे लगता है कि आपका मतलब है, NSStringFromSelector (@selector (doWork)) – jpswain

+0

और वह चयनकर्ता क्या करता है? क्या हमें ब्लॉक या कुछ निर्दिष्ट नहीं करना चाहिए? –

8

मुझे लगता है कि यह थोड़ा और अधिक जटिल से पिछले उत्तरदाताओं के उत्तरों का सुझाव दे सकता है ... अगर आप वास्तव में वास्तव में एक चयनकर्ता बनाने करना चाहते हैं ... बस नहीं "एक फोन कहता था "है कि आप" के आसपास बिछाने है .. नया "विधि"

... आप एक समारोह सूचक है कि आपके द्वारा बुलाया जाएगा बनाने की जरूरत "इतनी [self theMethod:(id)methodArg]; की तरह एक विधि के लिए, आपके द्वारा लिखी होगी ...

void (^impBlock)(id,id) = ^(id _self, id methodArg) { 
    [_self doSomethingWith:methodArg]; 
}; 

और फिर आपको IMP उत्पन्न करने की आवश्यकता है गतिशील रूप से ब्लॉक, इस बार, गुजर, "स्व", SEL, और किसी भी तर्क ...

void(*impFunct)(id, SEL, id) = (void*) imp_implementationWithBlock(impBlock); 

और (अपनी कक्षा में जोड़ने के पूरे चूसने वाला के लिए एक सटीक विधि हस्ताक्षर के साथ, इस मामले "[email protected]:@" में , शून्य वापसी, वस्तु फोन करने वाले, वस्तु तर्क)

class_addMethod(self.class, @selector(theMethod:), (IMP)impFunct, "[email protected]:@"); 

आप runtime shenanigans, in one of my repos, here.

3

इस तरह मैं जानता हूँ कि यह बहुत पहले के लिए उत्तर दिया गया है कुछ अच्छे उदाहरण देख सकते हैं, लेकिन अभी भी मैं शेयर करना चाहते हैं। यह sel_registerName का उपयोग करके भी किया जा सकता है।

प्रश्न में उदाहरण कोड इस तरह फिर से लिखा जा सकता है:

+0

दरअसल, @ टॉरस्टन-मरेक द्वारा वर्णित 'NSSelectorFromString'' हुड के तहत' sel_registerName'' का उपयोग करता है। [appledev] (https://developer.apple.com/documentation/foundation/1395294-nsselectorfromstring?language=objc): _ "NSSelectorFromString sel_register नाम के लिए एक चयनकर्ता नाम का एक यूटीएफ -8 एन्कोडेड वर्ण प्रस्तुत करता है और उस फ़ंक्शन द्वारा लौटाए गए मान को वापस देता है "_ – PLG