2011-08-31 23 views
11

मेरे पास माइप्रोटोकॉल नामक एक प्रोटोकॉल है।वर्ग बनाना मौजूदा विधियों के लिए श्रेणी के साथ प्रोटोकॉल के अनुरूप है

- (NSUInteger)length; 

और कुछ अन्य तरीकों: MyProtocol एक आवश्यक विधि है।

अब मैं एनएसएसटींग क्लास को एक श्रेणी के साथ माइप्रोटोकॉल के अनुरूप बनाना चाहता हूं। इसलिए जैसा:

@interface NSString (NSStringWithMyProtocol) <MyProtocol> 
@end 

इस श्रेणी में मैं 'लंबाई' विधि को छोड़कर सभी तरीकों को लागू करने, क्योंकि मैं मूल NSString कार्यान्वयन चाहते हैं। मैं इस विशेष कक्षा में इसे ओवरराइड नहीं करना चाहता हूं।

अब मुझे श्रेणी में माइप्रोटोकॉल के अपूर्ण कार्यान्वयन के कारण चेतावनी मिलती है।

मुझे पता है कि इसे हल करने के कुछ समाधान हैं।

  1. विधि वैकल्पिक
  2. सूचक Swizzling
  3. वर्ग के लिए उपवर्ग जो प्रोटोकॉल के अनुरूप है जोड़ा जा रहा है सुनिश्चित करें। फिर कार्यान्वयन छोड़ दें।

मैं इन विकल्पों का उपयोग नहीं करना चाहता क्योंकि उनके परिणामस्वरूप मेरे शेष कोड के लिए एक खराब डिज़ाइन है।
विकल्प 3 खराब है, मौजूदा प्रत्यक्ष उपखंडों के कारण प्रोटोकॉल के अनुरूप नहीं होगा।

क्या कोई जानता है कि लंबाई विधि को लागू किए बिना चेतावनी को कैसे हटाया जाए?

नोट: कक्षा, श्रेणी और प्रोटोकॉल केवल उदाहरण हैं। मुझे इस समस्या का सामना अन्य वर्गों के साथ हुआ जो मैं पोस्ट नहीं कर सका। धन्यवाद

संपादित करें: तीसरा विकल्प जोड़ा गया।

पूर्ण कोड:

प्रोटोकॉल:

@protocol MyProtocol <NSObject> 

- (void) myMethod; 
- (NSInteger) length; 

@end 

श्रेणी हैडर:

#import <Foundation/Foundation.h> 
#import "MyProtocol.h" 

@interface NSString (MyProtocol) <MyProtocol> 
@end 

श्रेणी कार्यान्वयन:

@implementation NSString (MyProtocol) 

- (void)myMethod { 

} 

@end 

यह निम्नलिखित चेतावनियों में परिणाम देता है। Screen shot

मैं LLVM जीसीसी 4.2 और एप्पल LLVM 3.0 संकलक के साथ संकलन करने की कोशिश की:

Incomplete implementation 

Method in protocol not implemented 

इस स्क्रीनशॉट में आप मेरी चेतावनी देख सकते हैं। मैंने एक्सकोड 4.0.2 और एक्सकोड 4.2 पर भी संकलित किया। मैं ओएस एक्स 10.6.8 पर हूं।

उत्तर

7

मैं इस समस्या को पुन: उत्पन्न नहीं कर सकता। क्या आप कोड पोस्ट कर सकते हैं जो इसे प्रदर्शित करता है? 10.7 पर चेतावनी के बिना निम्नलिखित संकलन।

#import <Foundation/Foundation.h> 

@protocol MyProtocol <NSObject> 
- (NSUInteger)length; 
@end 

@interface NSString (NSStringWithMyProtocol) <MyProtocol> 
@end 

int main (int argc, const char * argv[]) { 
    @autoreleasepool { 
    id<MyProtocol> foo = @"foo"; 
    NSLog(@"%@", foo);  
    } 
    return 0; 
} 
+1

मैंने अपना कोड जोड़ा। मैं यह भी देखता हूं कि क्या अलग है। आपने श्रेणी के लिए कार्यान्वयन को परिभाषित नहीं किया है। –

+1

क्लैंग स्पष्ट रूप से जीसीसी की तुलना में इसके बारे में बहुत कठोर है। अधिकांश मामलों में, यह एक अच्छी बात है, लेकिन इस मामले में मेरा मानना ​​है कि आपने इसे वर्तमान कार्यान्वयन के किनारे पर धक्का दिया है। मैं झुकाव के खिलाफ एक दोष खुल जाएगा। –

+1

मुझे लगता है कि मैं इसे सही उत्तर के रूप में हस्ताक्षर करूंगा। ध्यान दें कि यह केवल तभी कार्य करेगा जब कक्षा पहले से ही प्रोटोकॉल में परिभाषित सभी विधियों को लागू करेगी। श्रेणियों के कार्यान्वयन प्रोटोकॉल के आंशिक कार्यान्वयन के साथ मौजूद नहीं हो सकता है। –

0

आप इस हैक का एक सा पर विचार हो सकता है, और मैं अगर यह भी काम करेंगे पता नहीं है, लेकिन कैसे के कार्यान्वयन में, केवल पढ़ने के संपत्ति के रूप में यह घोषित करने

@property (readonly, assign) NSUInteger length; 

और उसके बाद के बारे में अपनी श्रेणी, इसे @dynamic

+1

एक गेटर के लिए काम करना चाहिए, लेकिन सेटटर के लिए नहीं। यह इंगित नहीं किया कि यह सिर्फ एक उदाहरण था। मेरे उत्पादन कोड के बारे में बात करने में सक्षम नहीं था। –

+0

@ मैट्स: इसे पढ़ने/लिखने की संपत्ति बनाएं, फिर – JeremyP

+1

सही। लेकिन यह न केवल सेटटर/गेटर प्रकार के तरीकों को हल करेगा। जैसा कि मेरी पिछली टिप्पणी में उल्लेख किया गया है, मैं अन्य वर्गों और विधियों से निपटता हूं। –