2009-07-16 7 views
64

क्या -respondsToSelector: के समतुल्य एक क्लास विधि है?कक्षा विधि समकक्ष के समतुल्य चयनकर्ता:

कुछ +respondsToSelector: जैसे कुछ?

कारण मैं पूछ रहा हूँ क्योंकि एक वर्ग स्तर पर -respondsToSelector: को लागू करने से, मैं एक संकलक चेतावनी मिलती है: "मिला '-respondsToSelector:' के बजाय '+ respondsToSelector:' प्रोटोकॉल (रों) में"।

कोड इस तरह दिखता है:

Class <SomeProtocol> someClass = [someInstance class]; 

if ([someClass respondsToSelector:@selector(someSelector:)]) { 
    someVar = [someClass someSelector:someData]; 
} 

उत्तर

80

अद्यतन करने के लिए अपने संपादित:

एक वर्ग ऑब्जेक्ट, जो respondsToSelector: ठीक से प्रतिक्रिया करता है जैसा कि आप शायद के बारे में पता कर रहे हैं। एक परीक्षण आवेदन में, मैं किसी भी संकलक बिना चेतावनी के निम्न में से दोनों कर सकते हैं:

NSLog(@"Responds to selector? %i", [MyObject respondsToSelector:@selector(respondsToSelector:)]); 
NSLog(@"Responds to selector? %i", [[MyObject class] respondsToSelector:@selector(respondsToSelector:)]); 

लेकिन, आप अपने चर पर एक प्रोटोकॉल घोषित किया है, तो यह मान लिया गया है कि वर्ग वस्तु आप इशारा कर रहे हैं उन को लागू करता है करने के लिए तरीकों। respondsToSelector: पर कॉल करने के उद्देश्य से id के रूप में someClass को सबसे आसान समाधान डालना होगा। एक कुछ हद तक सफाई घोल अपनी खुद की @protocol जो +respondsToSelector:(SEL)selector वाणी घोषित करने के लिए, और फिर someClass घोषित इस प्रकार होगा:

Class<SomeProtocol, ClassRespondingToSelector> someClass = ... 

अंत में, http://bugreporter.apple.com पर एप्पल पर बग के लिए सुनिश्चित हो। एक साधारण परीक्षण आवेदन शामिल करें ताकि यह स्पष्ट हो कि आप क्या कर रहे हैं। वे ऐसी बग रिपोर्ट का स्वागत करते हैं, भले ही उन्हें अतीत में सबमिट किया गया हो, क्योंकि इससे उन्हें फिक्स को प्राथमिकता देने में मदद मिलती है।

अंतिम नोट: यह शायद क्योंकि सिद्धांत में हो रहा है, तो आप एक जड़ वस्तु पूरी तरह NSObject से अलग लागू करने के लिए है कि मामले में, यह नहीं होगा-respondsToSelector: पर प्रतिसाद देने की चुन सकते थे, और। -[NSObject respondsToSelector:] वास्तव में NSObject प्रोटोकॉल में घोषित किया गया है, क्लास परिभाषा नहीं। NSObject प्रोटोकॉल वास्तव में है जहां आप NSObject के रूप में जो कुछ जानते हैं वह वास्तव में रहता है। कोई तर्क दे सकता है कि +respondsToSelector: भी वहां होना चाहिए, लेकिन अभी तक, यह नहीं है। और चूंकि आपने प्रोटोकॉल सूची प्रदान की है, और विधि वहां नहीं है, यह आपको यह सुनिश्चित करने के लिए चेतावनी देती है कि आप जानते हैं कि आप क्या कर रहे हैं।

+0

मुझे इस मामले में विश्वास है कि वह वास्तव में कक्षा में नहीं डालना चाहता, आईडी नहीं। –

+7

यह या तो हटाया गया कार्यक्षमता है या उत्तर अस्पष्ट है। 'कक्षा 'प्रतिक्रियाओं का जवाब नहीं देती है चयनकर्ता:'। – RileyE

+0

इसे आज़माएं। यह हेडर में नहीं है, लेकिन 'id classObject = [SomeClass क्लास] करें; [classObject प्रतिसाद देता है चयनकर्ता:] ' –

9

खैर एक वर्ग विधि, बस वर्ग वस्तु की एक विधि है, ताकि आप में सक्षम होना चाहिए बस को देखने के बाद इस

[MyClass respondsToSelector:@selector(...)] 
+0

मैं एक संकलक चेतावनी मिलती है की तरह व्यवहार करेगा: प्रोटोकॉल में "पाया '-respondsToSelector::' के बजाय '+ respondsToSelector' (रों) "। मैं इस कंपाइलर चेतावनी से कैसे छुटकारा पा सकता हूं? – firstresponder

+0

मैं प्रोटोकॉल प्रकार क्वालीफायर '' को छोड़कर संकलक चेतावनी से छुटकारा पा सकता हूं। ऐसा क्यों है? क्या यह वाक्यविन्यास सही नहीं है? – firstresponder

+3

पहले संवाददाता: उद्देश्य-सी एक गतिशील भाषा है। यदि आप उस प्रकार को (प्रोटोकॉल के साथ) के योग्यता के बिना 'कक्षा' या 'आईडी' पर कोई संदेश भेजते हैं, तो संकलक मानता है कि आप किसी प्रकार का उत्तर-चयनकर्ता चुनने वाले हैं या स्वयं की तरह की श्रेणी स्वयं की जांच कर रहे हैं । हालांकि, यदि आप किसी विशिष्ट वर्ग को प्रोटोकॉल या (उदाहरणों के लिए) निर्दिष्ट करते हैं, तो यह सहायक हो जाता है और आपके लिए चेक करता है। चूंकि आपने जिस प्रोटोकॉल को वैरिएबल घोषित किया है, उसके पास '+ प्रतिसाद नहीं है चयनकर्ता: 'घोषणा, संकलक एक चेतावनी उठाता है। –

1

मुझे लगता है कि आप क्या पूछ रहे थे: क्या आप +someMethod पर प्रतिक्रिया दे सकते हैं या नहीं? दूसरे शब्दों में, कोको टच एपीआई की सोच, आप चाहेंगे:

[ [ UIView class ] respondsToSelector: @selector(buttonWithType:) ] -> NO 
[ [ UIButton class ] respondsToSelector: @selector(buttonWithType:) ] -> YES 

लेकिन मैंने जो लिखा है वह वांछित के रूप में काम नहीं करता है। respondsToSelector: केवल उदाहरण विधियों के बारे में है। (इस प्रकार दोनों कॉल वापस नहीं आएंगे।) कोको एपीआई के भीतर कक्षा के लिए respondsToSelector: के बराबर नहीं है।

हालांकि, आप class_getClassMethod पर कॉल कर सकते हैं। यदि नतीजा गैर-नल है, तो क्लास विधि जिसे आप के बारे में पूछ रहे हैं मौजूद है और आप इसे कॉल कर सकते हैं।

+8

यह गलत है। 'प्रतिसाद देता है चयनकर्ता:' वर्ग विधियों के अस्तित्व की रिपोर्ट करने के लिए 'कक्षा' वस्तुओं पर बस ठीक काम करता है। –

+0

मैं इस दोस्त को अप-वोट करता हूं, क्योंकि वह वास्तव में अपने 'class_getClassMethod' दृष्टिकोण के साथ सही था। अगर मेरे पास पूरे धागे को पढ़ने के लिए पर्याप्त धैर्य है तो मुझे उसी समाधान को फिर से शुरू नहीं करना पड़ेगा। – bioffe

+1

मैं इसे डाउन-वोट करता हूं, क्योंकि क्लास ऑब्जेक्ट्स * क्लास ऑब्जेक्ट पर * इंस्टेंस विधियां हैं। – user102008

0

उद्देश्य सी में, कक्षाएं भी ऑब्जेक्ट्स हैं ताकि आप ऑब्जेक्ट संदेश भेज सकें। विशेष रूप से, आप कक्षा के -respondsToSelector: से पूछ सकते हैं। हालांकि आप गैर-वर्ग वस्तुओं के लिए कक्षा स्तर के तरीकों को नहीं भेज सकते हैं।

5

आप आईओएस 2.0 के बाद से निम्नलिखित instancesRespondToSelector: का उपयोग कर सकते हैं, इसलिए जहां आप कक्षा के उदाहरण के साथ कर सकते हैं;

[myInstance respondsToSelector: @selector(...)]; 
एक वर्ग के साथ

आप उपयोग कर सकते

[myClass instanceRespondsToSelector: @selector(...)]; 
// or 
[[myInstance class] instanceRespondsToSelector: @selector(...)]; 

कौन सा +(BOOL) respondsToSelector

+6

यह जवाब देगा कि कक्षा के उदाहरण चयनकर्ता को जवाब देंगे, न कि कक्षा स्वयं चयनकर्ता को सांख्यिकीय रूप से जवाब देगी। – Jonny

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