2012-02-10 14 views
37

addObserver:forKeyPath:options:context: का उपयोग कर किसी ऑब्जेक्ट पर कोई मान देखने पर, अंत में आप बाद में साफ करने के लिए उस ऑब्जेक्ट पर removeObserver:forKeyPath: पर कॉल करना चाहेंगे। ऐसा करने से पहले, क्या यह जांचना संभव है कि कोई वस्तु वास्तव में उस संपत्ति को देख रही है या नहीं?केवीओ - यह जांचने के लिए कि कोई ऑब्जेक्ट पर्यवेक्षक है या नहीं?

मैंने अपने कोड में यह सुनिश्चित करने का प्रयास किया है कि किसी ऑब्जेक्ट को केवल पर्यवेक्षक को हटाए जाने की आवश्यकता हो, लेकिन कुछ ऐसे मामले हैं जहां यह संभव है कि पर्यवेक्षक स्वयं को दो बार हटाने का प्रयास कर सके। मैं इसे रोकने के लिए काम कर रहा हूं, लेकिन बस मामले में, मैं यह पता लगाने की कोशिश कर रहा हूं कि अगर मेरा कोड वास्तव में किसी चीज़ का पर्यवेक्षक है तो पहले जांच करने का कोई तरीका है।

- (void *)observationInfo 

जो पर्यवेक्षकों की सूची चाहिए: NSKeyValueObserving प्रोटोकॉल के

+0

केवीओ क्योंकि इसमें एक क्रूड एपीआई है। पुस्तकालय उपलब्ध हैं जो इसके उपयोग को सरल बनाते हैं और आपको सुविधा के लिए ब्लॉक का उपयोग करने की अनुमति भी देते हैं। विवरण के लिए http://thirdcog.eu/pwcblocks/#goodies देखें। जब ऑब्जेक्ट को हटा दिया जाता है तो मुझे पर्यवेक्षकों को स्वचालित रूप से हटाने की क्षमता के साथ अपना स्वयं का कार्यान्वयन भी मिला है। यह अभी तक वास्तविक अनुप्रयोगों में परीक्षण नहीं किया गया है, लेकिन आप वैसे भी एक नज़र रखना चाहते हैं। गिटहब पर 'tastykvo' के लिए खोजें। –

उत्तर

43

[...] क्या यह जांचना संभव है कि कोई ऑब्जेक्ट वास्तव में संपत्ति देख रहा है या नहीं? जब एक अवलोकन आप को दूर करने कि सटीक अवलोकन के लिए जिम्मेदार हैं स्थापित करने

:

नहीं। जब KVO के साथ काम कर आप हमेशा ध्यान में निम्नलिखित मॉडल होना चाहिए। एक अवलोकन को इसके संदर्भ से पहचाना जाता है - इसलिए, संदर्भ अद्वितीय होना चाहिए। नोटिफिकेशन प्राप्त करते समय (और, शेर में, पर्यवेक्षक को हटाते समय) आपको हमेशा संदर्भ के लिए परीक्षण करना चाहिए, पथ नहीं।

मनाया वस्तुओं से निपटने है, हटाने और मनाया वस्तु के सेटर में अवलोकन स्थापित करने के लिए सबसे अच्छा अभ्यास:

static int fooObservanceContext; 

- (void)setFoo:(Foo *)foo 
{ 
    [_foo removeObserver:self forKeyPath:@"bar" context:&fooObservanceContext]; 

    _foo = foo; // or whatever ownership handling is needed. 

    [foo addObserver:self forKeyPath:@"bar" options:0 context:&fooObservanceContext]; 
} 

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 
{ 
    if (context == &fooObservanceContext) { 
     // handle change 
    } else { 
     // not my observer callback 
     [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; 
    } 
} 

- (void)dealloc 
{ 
    self.foo = nil; // removes observer 
} 

KVO का उपयोग करते समय आप यह सुनिश्चित करना है कि दोनों वस्तुओं, पर्यवेक्षक और observee, जब तक अवलोकन हो रहा है तब तक जीवित हैं।

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

एक अंतिम मुद्दा मैं इंगित करना चाहता हूं: मनाई गई संपत्ति केवीओ अनुपालन होनी चाहिए। You can't just observe anything

+0

क्या आपको किसी भी चीज़ पर fooObservanceContext सेट करने की आवश्यकता है, या क्या आप पर्यवेक्षक को जोड़ते समय ध्यान रखते हैं? – jrturton

+2

यह स्वचालित रूप से शून्य पर प्रारंभ होता है, लेकिन इस मामले में इसका उपयोग केवल इसके पते के लिए किया जाता है। हमें 'संदर्भ' के लिए एक अद्वितीय मूल्य की आवश्यकता है। चूंकि हम नहीं जानते कि अन्य लोग संदर्भ के रूप में क्या उपयोग करते हैं, यह एक ऐसा मूल्य बनाने का एक अच्छा तरीका प्रतीत होता है जो पहले उपयोग करने की संभावना नहीं है। –

+0

ठीक है, तो इसका पता है क्योंकि यह स्थैतिक है, और यही वह है जिसे आप उपयोग कर रहे हैं? मैं चीजों के उस तरफ बहुत गर्म नहीं हूं, स्पष्टीकरण के लिए धन्यवाद! – jrturton

25

भाग यह है।

EDIT केवल डीबगिंग के लिए उपयोगी।

+1

मैं सिर्फ इस प्रभाव का उत्तर लिख रहा था कि सूची स्पष्ट रूप से उपलब्ध नहीं है क्योंकि 'अवलोकन इंफो' को एक अपारदर्शी सूचक (जो वास्तव में, ऑब्जेक्ट हो सकता है या नहीं) लौटने के लिए प्रलेखित किया गया है। क्या यह सही लगता है? – Tommy

+0

@ टॉमी सबसे अधिक संभावना यह सटीक है। मैं सिर्फ डॉक्टर द्वारा जा रहा था जो कहता है "एक सूचक लौटाता है जो सभी पर्यवेक्षकों के बारे में जानकारी की पहचान करता है"। मुझे संदेह है कि आप इसे मुझसे कहीं ज्यादा गहराई से समझते हैं। – Rayfleck

+3

आप इसे उत्पादन कोड में उपयोग नहीं कर सकते हैं, लेकिन डीबगर में यह काफी उपयोगी है: टाइप करें 'po [seenObject observationInfo]' और आपको पर्यवेक्षकों और महत्वपूर्ण पथों का एक अच्छा अवलोकन मिलता है। –

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

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