2012-09-23 10 views
8

मेरे पास कुछ ऑब्जेक्ट रचनाओं के साथ एक मॉडल क्लास है, और मुझे इसके लिए इटरेटर लिखने का सबसे अच्छा तरीका नहीं पता है। अधिक जानकारी के में समस्या को देखने के लिए, यहाँ पदानुक्रम (सेमी-छद्म कोड) है:किसी संपत्ति की संग्रह संपत्ति (सही प्रकार के कास्टिंग के साथ) के लिए अपना खुद का इटरेटर कैसे लिखें?

एक रूट वर्ग:

MYEntity : NSObject 
@property int commonProperty; 
@property NSArray *childs; //Childs of any kind. 

कुछ ठोस उपवर्गों:

MYConcreteStuff : MYEntity 
@property int number; 

MYConcreteThing : MYEntity 
@property NSString *string; 

और के साथ एक जड़ वस्तु कंक्रीट संग्रह:

MYRoot : MYEntity 
@property MYEntity *stuff; //Collect only stuff childs here. 
@property MYEntity *things; //Collect only thing childs here. 

अब मैं संग्रह के लिए कूल सदस्य एक्सेसर्स लिख सकता हूं (MYEn में tity), जैसे:

-(MYEntity*)entityForIndex:(int) index 
{ 
    if ([self.childs count] > index) 
     return [self.childs objectAtIndex:index]; 

    return nil;  
} 

और रूट ऑब्जेक्ट के लिए भी अधिक शांत, अच्छी तरह से कास्ट सदस्य सदस्य एक्सेसर्स।

-(MYConcreteThing*)thingForIndex:(int) index 
{ 
    if ([self.things count] > index) 
     return (MYConcreteThing*)[self.things entityForIndex]; 

    return nil;  
} 

लेकिन मुझे नहीं पता कि इस तरह के संग्रह के लिए कुछ ऑनलाइनर इटरेटर कैसे लिखना है। पर डेप ग्राहक कोड कुछ की तरह है:

for (MYConcreteThing *eachThing in myRoot.things) 
    eachThing.string = @"Success."; //Set "thingy" stuff thanks to the correct type. 

मैं ब्लॉकों का उपयोग कर के बारे में सोच रही है, लेकिन वहाँ एक और अधिक स्वच्छ कटौती समाधान हो सकता है। कोई विचार/अनुभव?

उत्तर

8

मैं अब के लिए ब्लॉक के साथ आगे बढ़ूंगा, यह बहुत सरल है। अब मैं शब्द गणना को प्राथमिकता देता हूं।

बात enumaration के लिए एक ब्लॉक प्रकार (सही प्रकार सुनिश्चित):

typedef void (^MYThingEnumeratorBlock)(MYThing *eachThing); 

MYRoot में हालात के लिए एक शांत प्रगणक विधि (करने के लिए संग्रह का खुलासा नहीं):

-(void)enumerateThings:(MYThingEnumeratorBlock) block 
{  
    for (MYThing *eachThing in self.things.childs) 
     block(eachThing); 
} 

तो ग्राहक कोड है:

[myRoot enumerateThings:^(MYThing *eachThing) 
{ 
    NSLog(@"Thing: %@", eachThing.string);   
}]; 
कुछ साफ मैक्रो के साथ

:

#define ENUMARATE_THINGS myRoot enumerateThings:^(MYThing *eachThing) 

[ENUMARATE_THINGS 
{ 
    NSLog(@"Thing: %@", eachThing.string); //Cool "thingy" properties.   
}]; 
1

मेरी राय में ऐसा करने का सबसे अच्छा तरीका, सर वैल्यू कोडिंग अनुपालन विधियों को सरणी गुणों के लिए कार्यान्वित करना होगा। इसमें आपके ऑब्जेक्ट्स को अन्य ऑब्जेक्ट्स द्वारा देखने योग्य बनाने का अतिरिक्त बोनस होगा। आप apple documentation में इसके बारे में सब कुछ पढ़ सकते हैं। MYRoot क्लास में चीजें सरणी के लिए यहां एक उदाहरण कार्यान्वयन है। प्रत्येक विधि में कोड निजीकृत करने के लिए स्वतंत्र महसूस:

// KVC method for read-only array of Things 
- (NSUInteger) countOfThings 
{ 
    return _things.count; 
} 

- (Thing*) objectInThingsAtIndex:(NSUInteger)index 
{ 
    return [_things objectAtIndex:index]; 
} 

// Additional KVC methods for mutable array collection 
- (void) insertObject:(Thing*)thing inThingsAtIndex:(NSUInteger)index 
{ 
    [_things insertObject:thing atIndex:index]; 
} 

- (void) removeObjectInThingsAtIndex:(NSUInteger)index 
{ 
    [_things removeObjectAtIndex:index]; 
} 

संग्रह से अधिक पुनरावृति करने के लिए आप क्या करेंगे निम्नलिखित:

for (Thing *thing in [_entity valueForKey:@"things"]) { 
} 

सरणी में एक बात को जोड़ने के लिए तुम कर सकते हो

NSMutableArray *children = [_entity mutableArrayValueForKey:@"things"]; 
[children addObject:aThing]; 

ऐसा करने में आप यह सुनिश्चित करते हैं कि @"things" संपत्ति को देखकर सभी ऑब्जेक्ट को सरणी में सभी परिवर्तनों के बारे में सूचित किया जाएगा। यदि आप प्रविष्टि विधियों को सीधे कॉल करते हैं तो वे नहीं करेंगे (यह कभी-कभी अपने ही अधिकार में उपयोगी होता है)।

+0

यदि चीजें एक सरणी थीं, तो यह केवल केवीओ सामान के बिना (myRoot.things में चीज * चीज़) के लिए किया जा सकता है। – Geri

+0

लेकिन चीजें एक इकाई है जिसे बच्चे कहा जाता है। Thatswhy मुझे कुछ संकेत की जरूरत है। – Geri

+0

मैंने प्रश्न को और स्पष्ट करने के लिए संशोधित किया। या कम से कम सटीक। :) – Geri

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