5

एक तालिका को अद्यतन करने के लिए मुझे क्या करने की ज़रूरत है जब एक विधि कहा जाता है जो अंतर्निहित सरणी को अद्यतन करता है तो एक NSArrayController से बाध्य दृश्य देखें? एक उदाहरण यह स्पष्ट कर सकता है।एनएसएआरएआर कंट्रोलर और केवीओ

जब मेरा एप्लिकेशन लॉन्च होता है, तो यह सबवेट्रेन बनाता है। जब सबवेट्रेन शुरू किया जाता है, तो यह एक एकल सबवेकर बनाता है। सबवेकर में एक म्यूटेबल सरणी 'यात्रियों' है। जब एक सबवे कार शुरू की जाती है, यात्रियों की सरणी बनाई जाती है, और कुछ लोगों की वस्तुओं को रखा जाता है (चलो नाम "टिकट कलेक्टर" नामक एक व्यक्ति और दूसरा, "बेघर लड़का" नाम दिया गया है)। ये लोग हमेशा सबवेकर पर रहते हैं, इसलिए मैं उन्हें प्रारंभिकरण में बना देता हूं और उन्हें यात्रियों की सरणी में जोड़ता हूं।

आवेदन के जीवन के दौरान लोग कार पर चढ़ते हैं। सबवेकर पर 'एड पैसेंजर' कहा जाता है, जिसमें व्यक्ति एक तर्क के रूप में पारित होता है।

मेरे पास एक NSArrayController subwayTrain.subwayCar.passengers से जुड़ा हुआ है, और लॉन्च होने पर मेरा टिकट कलेक्टर और बेघर लड़का ठीक दिखता है। लेकिन जब मैं [सबवेकर एड पैसेंजर:] का उपयोग करता हूं, तो तालिका दृश्य अद्यतन नहीं होता है। मैंने पुष्टि की है कि यात्री निश्चित रूप से सरणी में जोड़ा जाता है, लेकिन गुई में कुछ भी अपडेट नहीं होता है।

मुझे गलत क्या करने की संभावना है? मेरा वृत्ति यह है कि यह केवीओ से संबंधित है - ऐड नियंत्रक को अपडेट करने के बारे में पता नहीं है जब ऐडपैसेंजर को कॉल किया जाता है (भले ही ऐडपैसेंजर कॉल करता है [यात्रियों को जोड़ता है:]। मैं यहां क्या गलत हो सकता हूं - अगर यह मदद करता है तो मैं कोड पोस्ट कर सकता हूं।

किसी को बाहर करने में मदद करने के लिए तैयार करने के लिए धन्यवाद।

अद्यतन

तो, यह पता चला है कि मैं इस

करने से

[seatedPlayers addObject:person]; 

addPassenger विधि से बदलकर काम करने के लिए प्राप्त कर सकते हैं 210

NSMutableSet *newSeatedPlayers = [NSMutableSet setWithSet:seatedPlayers]; 

[newSeatedPlayers addObject:sp]; 

[seatedPlayers release]; 

[self setSeatedPlayers:newSeatedPlayers]; 

मुझे लगता है कि ऐसा इसलिए है क्योंकि मैं [स्वयं सेटसेटेड प्लेयर्स] का उपयोग कर रहा हूं। क्या यह करने का सही तरीका है? यह सरणी की प्रतिलिपि बनाने के लिए बहुत ही बोझिल लगता है, पुराने को छोड़ दें, और प्रतिलिपि अपडेट करें (जैसा कि मौजूदा सरणी में जोड़ने के विपरीत है)।

+0

तालिका दृश्य नियंत्रक को कैसे बाध्य किया जाता है? क्या आपके पास प्रत्येक सारणी स्तंभ 'subwayTrain.subwayCar.passengers' की संपत्ति से जुड़ा हुआ है (उदा। कॉलम नाम 'subwayTrain.subwayCar.passengers.name' से जुड़ा हुआ है)? – outis

+0

वास्तव में हाँ। और जब यात्री लॉन्च होते हैं तो यात्री नाम दिख रहे हैं। –

उत्तर

1

तो, यह पता चला है कि मैं इस

NSMutableSet *newSeatedPlayers = [NSMutableSet setWithSet:seatedPlayers]; 
[newSeatedPlayers addObject:sp]; 
[seatedPlayers release]; 
[self setSeatedPlayers:newSeatedPlayers]; 

मुझे लगता है कि इस वजह से मैं [self setSeatedPlayers] उपयोग कर रहा हूँ करने के लिए

[seatedPlayers addObject:person]; 

से addPassenger विधि से बदलकर काम करने के लिए मिल सकता है। क्या यह करने का सही तरीका है?

पहले बंद, यह setSeatedPlayers: है, कोलन के साथ। उद्देश्य-सी में यह बेहद महत्वपूर्ण है।

अपने स्वयं के सेटर्स का उपयोग करना इसे करने का सही तरीका है, लेकिन आप गलत सही तरीके से उपयोग कर रहे हैं। यह काम करता है, लेकिन आप अभी भी अधिक कोड लिख रहे हैं जो आपको चाहिए।

आपको क्या करना चाहिए addSeatedPlayersObject: जैसे सेट एक्सेसर्स को कार्यान्वित करना है। फिर, खुद को वह संदेश भेजें। यह उन लोगों के लिए एक छोटी एक लाइनर जोड़ने बनाता है:

[self addSeatedPlayersObject:person]; 

और जब तक आप the KVC-compliant accessor formats का पालन के रूप में, आप मुक्त करने के लिए KVO सूचनाएं मिल जाएगा, तो आप setSeatedPlayers: साथ करते हैं।

setSeatedPlayers: पर इस का लाभ हैं:

  • सेट उत्परिवर्तित करने के लिए आपका कोड कम हो जाएगा।
  • क्योंकि यह छोटा है, यह क्लीनर होगा।
  • विशिष्ट सेट-उत्परिवर्तन एक्सेसर्स का उपयोग सामान्य-पूर्ण-डांग-सेट-बदली अधिसूचनाओं के बजाय विशिष्ट सेट-उत्परिवर्तन केवीओ नोटिफिकेशन की संभावना प्रदान करता है।

मैं भी दोनों संक्षिप्तता के लिए और क्योंकि यह है कि स्ट्रिंग शाब्दिक में महत्वपूर्ण गलत लिखा है करना बहुत आसान है mutableSetValueForKey: पर इस समाधान पसंद करते हैं,। (Uli Kusterer has a macro to cause a warning when that happens है, जो उपयोगी होता है जब आप वास्तव में KVC या KVO खुद से बात करने की जरूरत नहीं है।)

7

मुझे नहीं पता कि यह एक बग माना जाता है, लेकिन addObject: (और निकालें ऑब्जेक्ट: atIndex :) केवीओ अधिसूचनाएं उत्पन्न नहीं करते हैं, यही कारण है कि सरणी नियंत्रक/तालिका दृश्य अद्यतन नहीं हो रहा है। KVO-अनुपालन करने के लिए mutableArrayValueForKey का उपयोग करें:

उदाहरण:

[[self mutableArrayValueForKey:@"seatedPlayers"] addObject:person]; 

तुम भी insertObject लागू करने के लिए चाहता हूँ: inSeatedPlayersAtIndex: डिफ़ॉल्ट के बाद से KVO तरीकों वास्तव में धीमी गति से कर रहे हैं (वे एक पूरी नई सरणी बनाने के लिए, जोड़ने कि सरणी वस्तु, और नई सरणी के लिए मूल सरणी सेट - बहुत अक्षम)

- (void)insertObject:(id)object inSeatedPlayerAtIndex:(int)index 
{ 
    [seatedPlayers insertObject:object atIndex:index]; 
} 

ध्यान दें कि यह विधि भी जब एरे नियंत्रक वस्तुओं कहते हैं बुलाया जाएगा, तो के लिए अपने भी एक अच्छा हुक सोचता है एक पूर्ववत ऑपरेशन पंजीकरण की तरह , आदि।

1

मैं इस की कोशिश की है नहीं, इसलिए मैं यह नहीं कह सकते कि यह काम करता है, लेकिन नहीं आपको बुला रहा

insertObject द्वारा KVO सूचनाएं मिलेगा: atArrangedObjectIndex:

ArrayController पर

?

+0

हां, सरणी को म्यूट करने के लिए NSArrayController का उपयोग करके यह बनाता है कि NSArrayController उत्परिवर्तन के बारे में जानता है, और यह (और इसके लिए बाध्य चीजें) तदनुसार अद्यतन करना चाहिए। – ipmcc

0
  1. उपयोग willChangeValueForKey: और didChangeValueForKey: एक सदस्य का एक परिवर्तन के चारों ओर लिपटा जब परिवर्तन एक KVO अधिसूचना पैदा करने के लिए प्रकट नहीं होता। जब आप सीधे एक आवृत्ति चर बदल रहे हैं तो यह आसान होता है।

  2. willChangeValueForKey:withSetMutation:usingObjects: और didChangeValueForKey:withSetMutation:usingObjects: संग्रह की सामग्री के परिवर्तन के चारों ओर लपेटा गया है जब परिवर्तन केवीओ अधिसूचना का कारण नहीं दिखता है।

  3. चीजों को कम करने और उत्परिवर्तनीय सेट आवंटित करने से बचने के लिए [seatedPlayers setByAddingObject:sp] का उपयोग करें।के तहत 1. सबसे पहले विकल्प सूचीबद्ध कार्यों का एक स्वचालित मंगलाचरण के कारण

    [self setSeatedPlayers:[seatedPlayers setByAddingObject:sp]]; 
    
    बाद विकल्प के साथ

    :

कुल मिलाकर, मैं या तो ऐसा करने चाहते हैं:

[self willChangeValueForKey:@"seatedPlayers" 
      withSetMutation:NSKeyValueUnionSetMutation 
       usingObjects:sp]; 
[seatedPlayers addObject:sp]; 
[self didChangeValueForKey:@"seatedPlayers" 
      withSetMutation:NSKeyValueUnionSetMutation 
       usingObjects:sp]; 

या इस बेहतर प्रदर्शन करना चाहिए।

1

Key Value Observing के जादू की कुंजी Key Value Compliance में है। आप शुरुआत में एक विधि नाम addObject का उपयोग कर रहे थे: जो केवल "अनियंत्रित एक्सेसर पैटर्न" से जुड़ा हुआ है और आपकी संपत्ति एक अनुक्रमित संपत्ति (एनएसएमयूटेबलएरे) थी। जब आपने अपनी संपत्ति को एक अनियमित संपत्ति (एनएसएमयूटेबलसेट) में बदल दिया तो यह काम करता था। एनएसएआरएआरई या एनएसएमयूटेबलएरे को अनुक्रमित गुणों और एनएसएसएटी या एनएसएमयूटेबलसेट को अनियमित गुणों के रूप में मानें। जादू को होने के लिए क्या आवश्यक है यह जानने के लिए आपको वास्तव में इस खंड को ध्यान से पढ़ना होगा ... Key-Value-Compliance। विभिन्न श्रेणियों के लिए कुछ 'आवश्यक' विधियां हैं भले ही आप उनका उपयोग करने की योजना नहीं बनाते हैं।

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