2009-04-12 14 views
9

मैं एक संपत्ति के साथ एक सरल प्रोटोकॉल है:मुख्य मान एक प्रोटोकॉल वस्तु पर अवलोकन

@protocol StopsSource <NSObject> 
@property (retain,readonly) NSArray * stops; 
@end 

मैं कहीं और करने के लिए परिवर्तन को सुनने के लिए कोई मुख्य-मान पर्यवेक्षक जोड़ रहा " बंद हो जाता है "संपत्ति बदल गया है:"

id<StopsSource> source = ... 
[source addObserver:self 
     forKeyPath:@"stops" 
      options:NSKeyValueObservingOptionNew 
      context:nil]; 

कोड काम करता है कि में होने की उम्मीद के रूप में मैं जब observeValueForKeyPath ईवेंट प्राप्त संपत्ति "बंद हो जाता है।

warning: '-addObserver:forKeyPath:options:context:' not found in protocol(s) 

'addObserver' विधि NSObject करने के लिए एक वर्ग में परिभाषित किया गया है:

@interface NSObject(NSKeyValueObserverRegistration) 

वहाँ किसी भी तरह से यह चेतावनी ड्रॉप करने XCode पाने के लिए है असली झुंझलाहट addObserver फोन पर एक संकलक चेतावनी है ? यह मेरी समझ है कि प्रोटोकॉल श्रेणियों को अपनाने नहीं कर सकते हैं, इसलिए मुझे यकीन नहीं है कि एनएसकेईवैल्यू ऑब्सर्वर पंजीकरण प्रक्रिया को मेरे प्रोटोकॉल में कैसे लाया जाए, प्रोटोकॉल में घोषणाओं की प्रतिलिपि बनाने से कम, जो एक हैक जैसा प्रतीत होता है।

मुझे पता है कि यह एक छोटी सी समस्या है, जिसमें यह केवल एक कंपाइलर चेतावनी है, लेकिन मुझे यह जानने में दिलचस्पी है कि इसका समाधान करने का कोई "सही" तरीका है या नहीं।

+2

Abizern देखते हैं जवाब है, लेकिन अपने विशिष्ट समस्या के लिए , NSObject * स्रोत = ... –

उत्तर

12

असली झुंझलाहट addObserver फोन पर एक संकलक चेतावनी है:

warning: '-addObserver:forKeyPath:options:context:' not found in protocol(s) 

'addObserver' विधि NSObject करने के लिए एक वर्ग में परिभाषित किया गया है:

@interface NSObject(NSKeyValueObserverRegistration) 

क्या एक्सकोड इसे छोड़ने का कोई तरीका है चेतावनी?

Xcode (लोअरकेस ग) केवल आपके चेतावनी दिखा रहा है; यह जीसीसी, कंपाइलर है, जो आपको पहली जगह चेतावनी दे रहा है।

आप प्रोटोकॉल NSObject साथ वर्ग NSObject भ्रमित कर रहे हैं। एनएसओब्जेक्ट क्लास एनएसओब्जेक्ट प्रोटोकॉल के अनुरूप है, लेकिन प्रोटोकॉल के पास कक्षाओं के लिए स्वयं का कोई संबंध नहीं है। आपका स्टॉपसोर्स प्रोटोकॉल, प्रोटोकॉल होने के नाते, एनएसओब्जेक्ट प्रोटोकॉल से प्राप्त होता है, न कि एनएसओब्जेक्ट क्लास।

आपका घोषणा केवल उन दो प्रोटोकॉल, और नहीं किसी भी विशिष्ट वर्ग को शामिल किया गया है, तो यह उन प्रोटोकॉल कि NSObject वर्ग (जैसे KVO के रूप में) लागू कर सकते हैं बाहर कुछ भी शामिल नहीं है। यही कारण है कि आपको चेतावनी मिलती है।

के रूप में जेसन कोको अपने प्रश्न पर अपनी टिप्पणी में आपका बताया, समाधान घोषणा NSObject वर्ग के साथ साथ अपने प्रोटोकॉल का उपयोग करने को बदलने के लिए है:

NSObject <StopsSource> *source = …; 
महत्वपूर्ण जानकारी के लिए
0

मुझे लगता है कि आप प्रोटोकॉल के बारे में उलझन में पड़ सकते हैं; यह केवल संचालन के एक सेट को परिभाषित करता है जिसे किसी अन्य वर्ग द्वारा कार्यान्वित किया जा सकता है।

आपके प्रोटोकॉल में एकमात्र चीज एक संपत्ति है।

इसके अलावा, आप इसे NSObject प्रोटोकॉल के अनुरूप क्यों घोषित कर रहे हैं? आपको ऐसा करने की आवश्यकता नहीं है क्योंकि यदि आपके पास एक वर्ग है जो आपके प्रोटोकॉल को गोद लेता है, तो यह एनएसओब्जेक्ट से प्राप्त होगा, और इसके अनुरूप होगा। यानी

@interface YourClass : NSObject <StopSource> { 
    // etc 
@end 
+0

प्रोटोकॉल के साथ 'id ' को प्रतिस्थापित करें, प्रोटोकॉल में विधियों के अतिरिक्त गुण शामिल हो सकते हैं। MyXMLSupport प्रोटोकॉल उदाहरण देखें: http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocProtocols.html#//apple_ref/doc/uid/TP30001163-CH15-TPXREF148 –

+0

प्रोटोकॉल अक्सर एनएसओब्जेक्ट से विस्तारित होते हैं ताकि वे एनएसओब्जेक्ट विधियों का जवाब दे सकें जैसे चेतावनी उठाए बिना रिलीज/रिलीज/प्रतिक्रियाएं चयनकर्ता। अधिक जानकारी के लिए, देखें: http://stackoverflow.com/questions/679822/why-tack-a-protocol-of-nsobject-to-a-protocol-implementation –

+0

मैं आपके अंक देखता हूं, लेकिन यदि आप सभी हैं ऐसा करना एक एकल संपत्ति एक्सेसर को अनिवार्य करना है जिसे आपको कक्षा में बनाना होगा जो प्रोटोकॉल को गोद लेता है, यह अतिसंवेदनशीलता की तरह लगता है। – Abizern

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