2011-12-18 8 views
6

मान लें कि:यदि प्रोटोकॉल विधि को चिह्नित किया गया है, जिसे लागू नहीं किया गया है, तो संकलक क्यों चेतावनी जारी करता है और कोई त्रुटि नहीं?

  • नए प्रोटोकॉल घोषित किया जाता है
  • इस प्रोटोकॉल में विधि चिह्नित है @required
  • कक्षा प्रोटोकॉल के अनुरूप
  • क्लास करता नहीं विधि प्रोटोकॉल
  • में
उल्लेख लागू

संकलन समय पर, इस विधि के बारे में जानकारी ज्ञात है: यानी कि यह आवश्यक है और कि इस वर्ग और इस वर्ग के किसी अन्य वर्ग का विस्तार हो सकता है इसे लागू नहीं किया जाता है।

इस मामले में संकलक चेतावनी जारी करता है और कोई त्रुटि नहीं?

उत्तर

6

त्रुटियां तब जारी की जाती हैं जब संकलक जारी नहीं रह सकता क्योंकि कुछ गलत हो गया था।

उद्देश्य-सी में एक विधि को कॉल करते समय, विधि लुकअप रनटाइम के दौरान किया जाता है और संकलन के दौरान नहीं, जो सी ++ करता है। उद्देश्य-सी में "संदेश" ऑब्जेक्ट को बस भेजा जाता है, obj.executeCommand("Hey, can you execute function <name> for me?") जैसे कुछ। सी ++ में ऑब्जेक्ट को सीधे obj.<name>() जैसे तरीके से कॉल किया जाएगा। उद्देश्य-सी के मामले में executeCommand() विधि कहा जाता है, जो मौजूद है। सी ++ के मामले में फ़ंक्शन को कॉल किया जाता है लेकिन यह अस्तित्व में नहीं है। ये वे तरीके हैं जो कंपाइलर स्तर से जुड़े हुए हैं, जिसका अर्थ है कि वे दोनों नामों के बजाय स्मृति पते बन जाते हैं। executeCommand 0x12345678 बन जाता है लेकिन यह अभी भी एक ही संदेश ("execute function <name>") का उपयोग करता है।

यह शायद बहुत भ्रमित है, लेकिन यह विभिन्न भाषाओं में तरीकों को लागू करने के तरीकों से संबंधित है।

0

मुझे असली उत्तर नहीं पता है, लेकिन यहां एक उपयोग केस है जो इसके खिलाफ होगा।

क्या होगा यदि आपने किसी श्रेणी में सभी प्रोटोकॉल विधियों को लागू किया है ???

मुख्य इंटरफ़ेस घोषणा प्रोटोकॉल को गोद लेती है हालांकि प्रोटोकॉल विधि कार्यान्वयन एक श्रेणी में है। यह वैध कोड है लेकिन संकलक त्रुटि दिखाएगा यदि संकलक उस सख्त थे !!

2

यदि आप इसके बारे में दृढ़ता से महसूस करते हैं, तो -Werror क्यों नहीं चालू करें?

0

उद्देश्य-सी गतिशील भाषा है। एक कार्यान्वयन क्या है, इसका विचार एक स्थिर भाषा से अलग है।
अधिकांश भाग के लिए, यह कोड में है कि हम में से अधिकांश @ कार्यान्वयन ... @end ब्लॉक के अंदर लागू होते हैं।
लेकिन यदि कोई विधि नहीं मिली तो क्या होगा? फिर किसी वस्तु के पास गतिशील रूप से इसका मौका होता है।

कल्पना कीजिए कि आप एक ध्वनि प्रभाव खिलाड़ी के लिए एक इंटरफेस है:

@protocol FX 
- (void)playBeep; 
- (void)playSiren; 
- (void)playHonk; 
@end 

कार्यान्वयन फ़ाइलों Beep.mp3, Siren.mp3, हार्न हो सकता था।एमपी 3, लेकिन इसके बजाय तरीकों में से प्रत्येक को लागू करने के खेलने के लिए, यह -forwardInvocation रद्द कर सकते थे: और चयनकर्ता स्ट्रिंग, इस स्यूडोकोड की तरह कुछ पार्स:

NSString *selName = NSStringFromSelector([invocation selector]); 
if ([selName startsWith:@"play"]) { 
    NSString filename = fileNameFromSelector(selName); 
    [self playSoundFileNamed:filename]; 
} 

यह काल्पनिक लग सकता है, लेकिन एक बार आप का उपयोग शुरू भाषा की गतिशील विशेषताएं, आप अधिक से अधिक स्थानों को खोजना शुरू कर देंगे जहां यह समझ में आता है। और मतलब से मेरा मतलब है, क्या यह प्रयास लंबे समय तक मदद करता है?

उपर्युक्त मामले में, बस इंटरफ़ेस में एक-साउंड * विधि नाम जोड़ें, और एक उचित नामित ध्वनि फ़ाइल में ड्रॉप करें। यह सिर्फ काम करता है।

व्यक्तिगत प्रयोगों से एक और उदाहरण: कोर डेटा इकाइयों से अधिक प्राकृतिक तरीके से कैसे निपटें। मैं यह करना चाहता हूं: एनएसएआरएआरई * लोग = [व्यक्ति ढूंढेंअल्विथनाम जैसा: @ "बी%"]; भविष्यवाणियों के साथ मिलकर, अनुरोधों को लाने आदि के बजाय
लेकिन मैं कोड में विधि के हर क्रमपरिवर्तन को परिभाषित नहीं करना चाहता हूं।

अगर मैं एक एक्सएमएल बिल्डर बनाना चाहता हूं तो कैसे? मैं एक गतिशील दृष्टिकोण को देखता हूं। इसने ग्रोवी बिल्डर्स को अच्छी तरह से सेवा दी है (उदाहरण के लिए ग्रोवी/ग्रेल्स देखें)।

एक आखिरी उदाहरण: मेरे पास एक विशेषता प्रणाली है जहां मैं विधियों के समूहों के रूप में व्यवहार परिभाषित कर सकता हूं और मेरी वस्तुओं को इस व्यवहार को आत्मसात कर सकता हूं। इसलिए, जबकि कंपाइलर इंटरफ़ेस के लिए कार्यान्वयन नहीं देखता है, मेरी ऑब्जेक्ट के अनुरूप है, उद्देश्य-सी रनटाइम का उपयोग करके कार्यान्वयन को एक विशेषता वर्ग से इंजेक्शन दिया जाता है। मेरे द्वारा ऐसा क्यों किया जाएगा? मुझे बॉयलर प्लेट के कई प्रतिनिधि तरीके मिलते हैं, लेकिन साथ ही, प्रत्येक स्थिति के लिए एक एकल बेस क्लास पर्याप्त लचीला नहीं है। कोड नमूने से कट और पेस्ट करने के बजाय, मेरे 'नमूने' संकलित और दौड़ :) और किसी भी बदलाव विशेषता का उपयोग कर सभी परियोजनाओं में परिलक्षित होते हैं।

वास्तव में यह समझने के लिए कि यह सब आपके लिए क्यों उपलब्ध है, यह एक छोटे से पर्यावरण के साथ खेलना लायक है (फेरो या स्क्वाक खोजें)। यह वह जगह है जहां उद्देश्य-सी की जड़ें हैं।

और अंत में, को रोकने के लिए इन चेतावनियों:

#pragma clang diagnostic push 
#pragma clang diagnostic ignored "-Wprotocol" 

@implementation ... @end 

#pragma clang diagnostic pop 
0

क्योंकि वहाँ कई बार जब वहाँ फर्जी हैं "आवश्यक" एक खराब तरीके से तैयार प्रोटोकॉल में तरीके हैं। वे वैकल्पिक होना चाहिए था लेकिन किसी ने जोर दिया कि वे "आवश्यक" हैं। इस प्रकार संकलन बग के बजाए इसे रन टाइम मुद्दा बनाना बहुत बुद्धिमान है।