2012-03-08 20 views
5

मैं KVO का उपयोग कर शब्दकोश में परिवर्तन का पालन करने की कोशिश कर रहा हूँ।NSMutableDictionary KVO

उदाहरण:

dictionary = [NSMutableDictionary new]; 
[dictionary setObject:@"test1" forKey:@"key1"]; 
[dictionary setObject:@"test2" forKey:@"key2"];  
[dictionary setObject:@"test3" forKey:@"key1"]; 

मैं जब भी एक मूल्य के शब्दकोश में जोड़ा जाता है के लिए एक पर्यवेक्षक हुक करने में सक्षम होने की खुशी होगी। हटा दिया, या बदल दिया

निष्कर्ष में

तो (यानी ऊपर मामलों, जब भी setObject से किसी भी विधि कहा जाता है में): मैं एक समारोह

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context 

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

नहीं: मैं नहीं चाहता कि जो कुंजी मैं के लिए देख रहा हूँ निर्दिष्ट करने के लिए करना चाहते हैं। (उदाहरण के लिए केवल तब देखें जब @ "key1" जोड़ा जाता है) क्योंकि यह समाधान स्केल नहीं करता है।

+0

यदि आप शब्दकोश पर कुंजी '@ "@ गिनती देखते हैं तो क्या होता है? –

+0

नहीं। काम नहीं किया। अगर मैं @ "@2" के साथ @ "@ count" को प्रतिस्थापित करता हूं तो यह काम करता है लेकिन यह एक यूनिवर्सल समाधान नहीं है। –

उत्तर

0

आप NSMutableDictionary उपवर्ग और विभिन्न setters पर हावी नहीं कर सकते हैं? उदाहरण के लिए, अधिभावी setObject: forKey: सुपर बुला, तो तुरंत addObserver बुला ...

तुम भी NSMutableDictionary के लिए एक आवरण जहां आप अपने आप को अंतर्निहित NSMutableDictionary हेरफेर करने के लिए कस्टम setters का उपयोग करने के लिए मजबूर लिख सकते हैं द्वारा।

शायद मैं अपनी सीमाओं या scalability उद्देश्यों में से किसी में अधिक संदर्भ की जरूरत है।

+0

एनएसएमयूटेबल डिक्शनरी (मेरे आश्चर्य के लिए बहुत अधिक) को ओवरराइड करना अवैध है। कॉलिंग [सुपर सेटऑब्जेक्ट: forKey:] एक सार तत्व के बारे में कुछ कहने का अपवाद का कारण बनता है। मैं संरचना के प्रति झुकाव कर रहा हूं और एक शब्दकोश प्रदान कर सकने वाले सभी कार्यों को पुन: कार्यान्वित कर रहा हूं (पीआईटीए और कोई भी पॉलिमॉर्फिक नहीं)। स्केलेबिलिटी समस्या इस तथ्य के संदर्भ में थी कि आप केवल शब्दकोश में "key1" में परिवर्तन देख सकते हैं और शब्दकोश में "*" परिवर्तन नहीं कर सकते हैं। इसलिए यदि मैं शब्दकोश में एक नई कुंजी जोड़ता हूं तो मैं पर्यवेक्षक को सूचित नहीं कर सकता। –

+0

वास्तव में दिलचस्प है। अब तक मुझे लगता है कि सजावटी वर्ग सबसे अच्छा विकल्प हो सकता है। हालांकि आपको सभी विधियों को फिर से लागू करने की आवश्यकता नहीं है। आपके पास किसी सदस्य के रूप में शब्दकोश हो सकता है और किसी भी गैर-केवो संचालन के लिए [myObject.dictionary nsdictionarymethod] को कॉल कर सकता है और बस, सेट, सेट विधियों को फिर से कार्यान्वित कर सकता है। – Vinnie

7

उपवर्गीकरण NSMutableDictionary तथ्य यह है कि NSDictionary और उसके मित्र वर्ग समूहों रहे हैं की वजह से, एक सा कष्टप्रद है। यह निश्चित रूप से करने योग्य है, और यदि आपको ऑब्जेक्ट को कक्षाओं के दूसरे समूह में पास करना है, तो आप इसे ठीक से करना चाहेंगे। अन्यथा, एक समग्र कक्षा बनाना आसान हो सकता है जिसमें एक ही मूल एपीआई है और भंडारण के लिए आंतरिक रूप से NSMutableDictionary ऑब्जेक्ट का उपयोग करता है। CocoaWithLove.com, Ordered Dictionary Subclassing के रूप में एक बहुत अच्छा लेखन है, जो ऐसा करने में चला जाता है।

हालांकि, कि पूरी तरह से आपकी समस्या का समाधान नहीं है। क्या मैं सुझाव है कि आप इस तरह के ऊपर एक के रूप में एक उपवर्ग या डेकोरेटर वर्ग के साथ शुरू करते हैं, तो -(NSArray*)allKeys के लिए स्पष्ट रूप से समर्थन जोड़ने, जो NSDictionary में एक मानक एक्सेसर है ही है। फिर, आप सभी के लिए परिवर्तन संदेशों के साथ पास करने के लिए समर्थन जोड़ सकते हैं, जो इसे देखने योग्य बना देगा।

यह -setObject:forKey: और -removeObjectForKey: तरीकों के संबंध में निम्न कोड जोड़ने के द्वारा किया जा सकता है।

- (void)setObject:(id)anObject forKey:(id)aKey 
{ 
    BOOL addKey=NO; 
    if (![dictionary objectForKey: aKey]) { 
     addKey=YES; 
     [self willChangeValueForKey: @"allKeys"]; 
    } 
    [dictionary setObject:anObject forKey:aKey]; 
    if (addKey) 
     [self didChangeValueForKey: @"allKeys"]; 
} 

- (void)removeObjectForKey:(id)aKey 
{ 
    [self willChangeValueForKey: @"allKeys"]; 
    [dictionary removeObjectForKey:aKey]; 
    [self didChangeValueForKey: @"allKeys"]; 
} 

यहाँ क्या किया जा रहा है कि हम वर्ग के लिए स्पष्ट KVO अधिसूचना जोड़ रहे हैं जब शब्दकोश की कुंजियों सरणी में एक परिवर्तन को चिह्नित करने के लिए बदल रहे हैं। कहते हैं और निकाल देता है की

यह ध्यान रखना होगा। आप परिवर्तनों को एक ही आधार पर सूचना प्राप्त करना चाहते हैं, तो आप बयान करता है, तो निकाल सकते हैं, और सिर्फ allKeys या तो सेट पर सूचित या निकालने के लिए, इस तरह है:

- (void)setObject:(id)anObject forKey:(id)aKey 
{ 
    [self willChangeValueForKey: @"allKeys"]; 
    [dictionary setObject:anObject forKey:aKey]; 
    [self didChangeValueForKey: @"allKeys"]; 
} 

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

+0

मैं इस निष्कर्ष से सहमत हूं। धन्यवाद गैज। मैं इसे लागू करने जा रहा हूँ। –

+0

यदि यह काम करता है, तो आपके द्वारा प्रदान किए गए उत्तरों को उत्तर देने के लिए मत भूलना और आपके समाधान प्रदान करने वाले उत्तर के रूप में चिह्नित करें। – gaige

+0

जब एनएसएमयूटेबल डिक्शनरी आकार में बढ़ता है, तो क्या उन तरीकों को प्रत्येक कुंजी के लिए फिर से नहीं बुलाया जाएगा ?? –

0

मुझे आशा है कि यह उपयोगी होगा

- (void)addObserver:(id)observer { 
    for (id key in grid) 
     [self addObserver:observer 
       forKeyPath:[key description] 
        options:0 
        context:key]; 
} 
0

मैं एक और तरीका यह करने के लिए नीचे दिए गए ओवरराइड उपयोग कर रहा है लगता है, बैठाना आप देख रहे हैं NSMutableDictionary "allRecentCurrencyData" जिनके मान recentBrazilReals पर निर्भर हैं, recentEuEuro, recentUkPounds, recentJapanYen , पर्यवेक्षक को बुलाया जाएगा, लेकिन दोष यह है कि आपको ऐसा करने के लिए हाथ से पहले चाबियाँ जाननी होंगी।

[self addObserver:self forKeyPath:@"[email protected]" options:0 context:NULL]; 

मेरा ऐप एक शास्त्रीय रास्ते में डेटा प्रबंधन करता है, एक tableview का उपयोग कर, एक:

+ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key 
{ 
    NSSet *keyPaths = [super keyPathsForValuesAffectingValueForKey:key]; 

    if ([key isEqualToString:@"allRecentCurrencyData"]) { 
     NSArray *affectingKeys = @[@"recentBrazilReals", @"recentEuEuro",@"recentUkPounds",@"recentJapanYen"]; 
     keyPaths = [keyPaths setByAddingObjectsFromArray:affectingKeys]; 
    } 
    return keyPaths; 
} 
1

मैं एक पर्यवेक्षक इस तरह से परिवर्तनशील शब्दकोश "अनुवादक" को जोड़कर एक समान समस्या हल नियंत्रक और शब्दकोश केवीओ संपत्ति "अनुवादक" के रूप में शब्दकोश। शब्दकोश मेरे एक्सआईबी में एक NSDictionaryController से जुड़ा हुआ है, और एक टेबलव्यू सामग्री नियंत्रक के लिए बाध्य है।

enter image description here

अब, निम्नलिखित मामलों में से किसी में मैं परिवर्तन को पकड़ने:

यह tableview के कनेक्शन हैं

  • एक कुंजी-मान पेयर
  • को हटाने जोड़ने एक कुंजी-मूल्य जोड़ी
  • एक कुंजी बदलना
  • changi एनजी एक मान

टिप्पणी: दुर्भाग्य से, यह दृष्टिकोण एनएसएमयूटेबलएरेज़ के साथ काम नहीं करता है। परिवर्तनों को पहचाना नहीं गया है

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