18

का उपयोग कर एक म्यूटेबल सरणी में परिवर्तनों का निरीक्षण करना मेरे मॉडल में मेरे पास ईवेंट नामक ऑब्जेक्ट्स हैं। जब भी कोई नई वस्तु घटनाओं में जोड़ दी जाती है, तो मैं अपने नियंत्रक को अधिसूचित करना चाहता हूं।केवीओ बनाम NSNotificationCenter

मैंने सोचा था कि जब घटनाओं परिवर्तन (एक नई वस्तु से जोड़ा जा रहा है) है कि एक अच्छा तरीका करने के लिए इस KVO पैटर्न का उपयोग किया जाएगा सूचना पाने के लिए

// AppDelegate 
// events is a NSMutableArray @property/@synthesize etc... 

[appDelagate addObserver:self 
       forKeyPath:@"events" 
        options:NSKeyValueObservingOptionNew 
        context:NULL]; 

लेकिन observeValueForKeyPath विधि नहीं था बुलाया जा रहा है और मुझे पता चला कि सरणी KVO अनुरूप :-(

एक विकल्प मैन्युअल मुख्यपथ

के लिए willChangeValueForKey फोन करके विधि को गति प्रदान करने के लिए है नहीं कर रहे हैं
// ViewController 
[self willChangeValueForKey:@"events"]; 
[self.events addObject:event]; 
[self didChangeValueForKey:@"events"]; 

लेकिन यह भारी लगता है के बाद से मैं शायद यह भी पहले का ट्रैक और मेरे घटनाओं सरणी के राज्य के बाद रखना चाहिए ताकि यह observeValueForKeyPath विधि से पहुँचा जा सकता।

एक दृष्टिकोण एक मानक सरणी (म्यूटेबल के बजाए) का उपयोग करने और हर बार जब मैं एक नई वस्तु जोड़ना चाहता हूं, तो ईवेंट का एक नया उदाहरण बनाने/सेट करने के लिए हो सकता है, या मैं एक अलग संपत्ति बना सकता हूं जो कितने ट्रैक रखता है आइटम म्यूटेबल सरणी में हैं (मेरी इच्छा है कि आप @ "events.count" देख सकें)।

एक और विकल्प NSNotificationCenter का उपयोग करना होगा। मैंने कुछ जवाब भी पढ़े हैं जो ब्लॉक का उपयोग करने का सुझाव देते हैं (लेकिन मुझे नहीं पता कि उस पर कहां से शुरू करना है)।

अंत में, क्या मैं अपने प्रतिनिधि में अपने नियंत्रक का उदाहरण रख सकता हूं और केवल एक प्रासंगिक संदेश भेज सकता हूं?

// Delegate 
[myController eventsDidChange]; 

क्या यह एक प्रतिनिधि से नियंत्रक का संदर्भ रखना अजीब है?

मैं यह समझने के लिए संघर्ष कर रहा हूं कि उपयोग करने का सबसे अच्छा तरीका कौन सा है, इसलिए प्रदर्शन, भावी कोड लचीलापन और सर्वोत्तम प्रथाओं पर कोई सलाह बहुत सराहना की जाती है!

उत्तर

18

आपको अपने ज्ञान के बिना उत्परिवर्तन से बचने के लिए उत्परिवर्तनीय संग्रहों के लिए प्रत्यक्ष सार्वजनिक गुण नहीं बनाना चाहिए। NSArray कुंजी-मूल्य स्वयं को देखने योग्य नहीं है, लेकिन आपकी एक से कई संपत्ति@"events" है। यह इस प्रकार से पालन करने के लिए है:

@interface Model 
@property (nonatomic, copy) NSArray *events; 
@end 
फिर अपने कार्यान्वयन में वापस यह एक परिवर्तनशील इवर साथ

:

सबसे पहले, एक अपरिवर्तनीय संग्रह के लिए एक सार्वजनिक संपत्ति की घोषणा

@interface Model() 
{ 
    NSMutableArray *_events; 
} 
@end 

और गेटर ओवरराइड और सेटर:

@implementation Model 

@synthesize events = _events; 

- (NSArray *)events 
{ 
    return [_events copy]; 
} 

- (void)setEvents:(NSArray *)events 
{ 
    if ([_events isEqualToArray:events] == NO) 
    { 
     _events = [events mutableCopy]; 
    } 
} 

@end 

यदि अन्य ऑब्जेक्ट्स को आपके मॉडल में ईवेंट जोड़ने की आवश्यकता है, वें आई -[Model mutableArrayValueForKey:@"events"] पर कॉल करके एक परिवर्तनीय प्रॉक्सी ऑब्जेक्ट प्राप्त कर सकता है।

NSMutableArray *events = [modelInstance mutableArrayValueForKey:@"events"]; 
[events addObject:newEvent]; 

यह प्रत्येक बार एक नए संग्रह के साथ संपत्ति सेट करके केवीओ अधिसूचनाओं को ट्रिगर करेगा।बेहतर प्रदर्शन और अधिक दानेदार नियंत्रण के लिए, शेष array accessors लागू करें।

यह भी देखें: Observing an NSMutableArray for insertion/removal

+2

धन्यवाद! mutableArrayValueForKey चाल करता है। क्या आपके पास मॉडल के नियंत्रक के बीच संवाद करना चाहते हैं, तो आप किस पैटर्न का उपयोग करना चाहते हैं (केवीओ, अधिसूचना केंद्र, प्रतिनिधि) के बारे में कोई सुझाव है? – MathewS

+0

मुझे निश्चित रूप से कुछ याद आ रहा है। क्या कोई कृपया बता सकता है कि अगर सेट जोड़ने या डालने के लिए सेट एवेन्ट्स कहलाए जाएंगे तो ऑब्जेक्ट: atIndex: बैकिंग म्यूटेबल सरणी पर ऑब्जेक्ट? –

0

प्रति docs on accessor methods, आप को लागू करना चाहिए: जब इन कहा जाता है

- (void)addEventsObject:(Event*)e 
{ 
    [_events addObject:e]; 
} 

- (void)removeEventsObject:(Event*)e 
{ 
    [_events removeObject:e]; 
} 

फिर KVO सूचनाएं सक्रिय हो जाएगा।

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