2009-08-09 13 views
5

कोको में, addObserver:forKeyPath:options:context: "न तो रिसीवर, न ही ऑब्सर्वर" बनाए रखता है। इसलिए मुझे लगता है कि स्वयं को अनुमति देने की अनुमति है; कि है, यह जब तक आप dealloc में पहली बात यह है के रूप में एक पर्यवेक्षक के रूप में self पंजीकरण रद्द करना याद के रूप में की तरहकोको में स्वयं को देखकर

[self addObserver:self forKeyPath...]

कुछ करने के लिए पूरी तरह से वैध है।

क्या यह धारणा सही है?

उत्तर

12

हां, वास्तव में कोई कारण नहीं है कि आप स्वयं का निरीक्षण नहीं कर सकते हैं। लेकिन जैसा कि आपने कहा था, किसी भी केवीओ अवलोकन की तरह, इसे हटाए जाने से पहले स्वयं को पर्यवेक्षक के रूप में निकालना सुनिश्चित करें।

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

1

ब्रायन वेबस्टर ने जो किया वह मैं करता हूं। यहाँ एक उदाहरण है:

//.h 
... 
@property(readwrite, retain, setter=setMyPropertySynth:) id myProperty; 
-(void)setMyProperty:(id)newValue; 
.... 


//.m 
... 
@synthesize myProperty; 

-(void)setMyProperty:(id)newValue 
{ 
    //add code here 

    [self setMyPropertySynth:newValue]; 

    //add more code here 
} 
... 
+0

यह एक अच्छा विचार नहीं है। आमतौर पर यह अपेक्षा की जाती है कि 'obj.foo = bar; '' [obj setFoo: bar]' के समतुल्य होना चाहिए; और इस पैटर्न से भटकने से आपके कोड को पढ़ने/बनाए रखने में – rpetrich

+0

@rpetrich मैं सहमत हूं कि यह नहीं है एक अच्छा विचार (मैंने 18 महीने पहले उस उत्तर को लिखा था), लेकिन एक अलग कारण के लिए। मैं अब '@ संश्लेषण' का उपयोग नहीं करूंगा; अब मैं पूरा गेटर और सेटर लिखूंगा। कुछ अतिरिक्त लाइनों का अतिरिक्त बोझ अतिरिक्त विधि कॉल के बाद मानसिक रूप से लागत से अधिक है (मैं अभी भी '@ property' का उपयोग करता हूं)। मैं असहमत हूं कि सेटर्स (या गेटर्स) में साइड इफेक्ट्स स्वाभाविक रूप से खराब हैं। जहां संभव हो उन्हें टालना चाहिए। उदाहरण के लिए, 'hypotheticalQueryObject.maxResults = 4;' सेट करना वैध रूप से एक और खोज को ट्रिगर कर सकता है। –

+0

@rpetrich वास्तव में इसकी गारंटी है। 'obj.foo = bar;' हमेशा 'setFoo:' के कार्यान्वयन का उपयोग करता है (भले ही आपने संश्लेषित एक ओवरराइड किया हो)। –

-1

-dealloc में एक पर्यवेक्षक न निकालें। क्यूं कर? क्योंकि जब आप कचरा कलेक्टर चालू करते हैं तो चीजें काम करना बंद कर देगी; -dealloc कभी नहीं बुलाया जाता है। आपको मेमोरी से संबंधित क्लीनअप कोड के लिए -dealloc और -finalize विधियों का उपयोग करना चाहिए।

+0

अच्छा बिंदु; लेकिन, इसके बजाय मैं क्या उपयोग करूं? –

+0

बस इसे ऑब्जेक्ट के जीवन चक्र के हिस्से के रूप में सेट करें। यदि वह चीज जो इसे बनाता है, उसे बताती है कि क्या देखना है, और इसे कब देखना बंद करना है, तो आप निर्भरताओं को इंजेक्शन कर रहे हैं जो आपके ऑब्जेक्ट को फिर से उपयोग और परीक्षण करने में आसान बनाता है। –

+3

... लेकिन गलत तरीके से उपयोग करना बहुत आसान है, और कोको स्मृति प्रबंधन को कम करता है। यदि प्रत्येक निर्माता को यह भी पता होना चाहिए कि बनाए गए ऑब्जेक्ट को पर्यवेक्षक को इस तरह और (जैसे विशेष रूप से यदि वह स्वयं है), तो हमने निजी जानकारी को कॉलर में स्थानांतरित कर दिया है, जो खराब है। इससे भी बदतर, अगर मुझे "अब आप को नष्ट कर दें" विधि की आवश्यकता है जो इस अवलोकन को पूर्ववत करता है, तो जीसी का पूरा बिंदु खिड़की से बाहर चला गया। हमारे पास सबसे अच्छा समाधान है गैर-स्मृति प्रबंधन टुकड़ों को डेलोक में डुप्लिकेट करना और अंतिम रूप देना (संभावित रूप से साझा दिनचर्या में बढ़ना)। इसमें NSNotificationCenter removeObserver भी शामिल है। –