यह धागा एक प्रकार का पुराना है, और जो मैं साझा करना चाहता हूं उसका अधिकांश हिस्सा पहले से ही यहां है।
हालांकि, मेरी पसंदीदा विधि का उल्लेख नहीं किया गया है, और AFAIK वर्तमान क्लैंग में कोई मूल समर्थन नहीं है, इसलिए यहां मैं जाता हूं ...
सबसे पहले, और सबसे महत्वपूर्ण (जैसा कि अन्य ने पहले ही बताया है) ऑब्जेक्टिव-सी में अमूर्त वर्ग कुछ बहुत ही असामान्य हैं - हम आमतौर पर इसके बजाय रचना (कभी-कभी प्रतिनिधिमंडल के माध्यम से) का उपयोग करते हैं। शायद यही कारण है कि इस तरह की सुविधा पहले से ही भाषा / संकलक में मौजूद नहीं है - @dynamic
गुणों के अलावा , जिसे IIRC को ओब्जेक्ट 2.0 में कोरडाटा के साथ जोड़ा गया है।
लेकिन यह देखते हुए कि (आपकी स्थिति के सावधानीपूर्वक मूल्यांकन के बाद!) आप इस निष्कर्ष पर पहुंचे हैं कि प्रतिनिधिमंडल (या सामान्य रूप से रचना) आपकी समस्या को हल करने के लिए अच्छी तरह से अनुकूल नहीं है, यहाँ मैं यह कैसे करूँ:
- बेस क्लास में हर अमूर्त पद्धति को लागू करें।
- इसे लागू करें
[self doesNotRecognizeSelector:_cmd];
...
- … इसके बाद
__builtin_unreachable();
आपको गैर-शून्य तरीकों के लिए मिलने वाली चेतावनी को चुप कराने के लिए आपको बताएंगे कि “नियंत्रण बिना रिटर्न के गैर-शून्य फ़ंक्शन के अंत तक पहुंच गया”।
- या तो चरण 2 और 3 को एक मैक्रो में संयोजित करें, या किसी श्रेणी में
-[NSObject doesNotRecognizeSelector:]
उपयोग किए बिना एनोटेट करें ताकि उस पद्धति के मूल कार्यान्वयन को प्रतिस्थापित न किया जा सके और अपनी परियोजना के पीसीएच में उस श्रेणी के हेडर को शामिल कर सकें।__attribute__((__noreturn__))
मैं व्यक्तिगत रूप से मैक्रो संस्करण को पसंद करता हूं जो मुझे बॉयलरप्लेट को यथासंभव कम करने की अनुमति देता है।
यह रहा:
// Definition:
#define D12_ABSTRACT_METHOD {\
[self doesNotRecognizeSelector:_cmd]; \
__builtin_unreachable(); \
}
// Usage (assuming we were Apple, implementing the abstract base class NSString):
@implementation NSString
#pragma mark - Abstract Primitives
- (unichar)characterAtIndex:(NSUInteger)index D12_ABSTRACT_METHOD
- (NSUInteger)length D12_ABSTRACT_METHOD
- (void)getCharacters:(unichar *)buffer range:(NSRange)aRange D12_ABSTRACT_METHOD
#pragma mark - Concrete Methods
- (NSString *)substringWithRange:(NSRange)aRange
{
if (aRange.location + aRange.length >= [self length])
[NSException raise:NSInvalidArgumentException format:@"Range %@ exceeds the length of %@ (%lu)", NSStringFromRange(aRange), [super description], (unsigned long)[self length]];
unichar *buffer = (unichar *)malloc(aRange.length * sizeof(unichar));
[self getCharacters:buffer range:aRange];
return [[[NSString alloc] initWithCharactersNoCopy:buffer length:aRange.length freeWhenDone:YES] autorelease];
}
// and so forth…
@end
जैसा कि आप देख सकते हैं, मैक्रो सार विधियों के पूर्ण कार्यान्वयन को प्रदान करता है, बॉयलरप्लेट की आवश्यक मात्रा को पूर्णतम तक कम कर देता है।
एक बेहतर विकल्प क्लैंग टीम को इस मामले के लिए फीचर अनुरोध के माध्यम से एक संकलक विशेषता प्रदान करने की पैरवी करना होगा । (बेहतर है, क्योंकि यह उन परिदृश्यों के लिए संकलन-समय के निदान को भी सक्षम करेगा जहां आप उदाहरण के लिए NSIncrementalStore उप-वर्ग करते हैं।)
क्यों मैं इस विधि का चयन
- यह कुशलता से काम किया है, और कुछ हद तक सुविधाजनक है।
- इसे समझना काफी आसान है। (ठीक है, जो
__builtin_unreachable()
लोगों को आश्चर्यचकित कर सकता है, लेकिन यह समझना काफी आसान है, भी)
- इसे अन्य कंपाइलर चेतावनियों या त्रुटियों को उत्पन्न किए बिना रिलीज़ बिल्डिंग्स में छीन लिया जा सकता है - एक दृष्टिकोण के विपरीत जो कि एक दावे के मैक्रोज़ पर आधारित है।
मुझे लगता है कि अंतिम बिंदु कुछ स्पष्टीकरण की जरूरत है:
कुछ (अधिकांश?) लोग रिलीज बिल्ड में जोर देते हैं। (मैं उस आदत से असहमत हूं, लेकिन यह एक और कहानी है ...) एक आवश्यक विधि को लागू करने में असफल रहा - हालांकि - बुरा , भयानक , गलत है , और मूल रूप से आपके कार्यक्रम के लिए ब्रह्मांड का अंत है । आपका कार्यक्रम इस संबंध में सही ढंग से काम नहीं कर सकता है क्योंकि यह अपरिभाषित है, और अपरिभाषित व्यवहार कभी भी सबसे खराब चीज है। इसलिए, नए डायग्नोस्टिक्स उत्पन्न किए बिना उन डायग्नॉस्टिक्स को छीनने में सक्षम होना पूरी तरह से अस्वीकार्य होगा।
यह काफी बुरा है कि आप इस तरह की प्रोग्रामर त्रुटियों के लिए उचित संकलन-समय निदान प्राप्त नहीं कर सकते हैं, और इसके लिए इन-रन-टाइम खोज का सहारा लेना होगा, लेकिन यदि आप रिलीज बिल्ड में इस पर प्लास्टर लगा सकते हैं, तो एक अमूर्त वर्ग होने का प्रयास क्यों करें। पहले स्थान पर?