2012-09-23 14 views
8

Bazı nesne kompozisyonları ile bir model sınıfım var ve bunun için yineleyiciler yazmanın en iyi yolunu bilmiyorum. Burada hiyerarşi (yarı sözde kod) 'dir, daha fazla ayrıntı sorunu görmek için:Bir mülkün bir koleksiyon özelliği için kendi yineleyicimi nasıl yazarım (doğru tipte döküm ile)?

A Kök sınıfı:

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

Bazı somut alt sınıfları:

MYConcreteStuff : MYEntity 
@property int number; 

MYConcreteThing : MYEntity 
@property NSString *string; 

Ve bir kök nesnesi ile beton koleksiyonlar:

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

Şimdi koleksiyonlar için (örneğin, MYEn) havalı üye girişlerini yazabilirim tity), like:

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

    return nil;  
} 

Kök nesneler için daha da havalı, iyi tipte döküm üyeler.

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

    return nil;  
} 

Ama nasıl böyle koleksiyonları için bazı oneliner yineleyicinızı yazmak için hiçbir fikrim yok. özenti istemci kod şey gibi:

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

Ben bloklarını kullanarak düşünüyorum, ancak daha temiz kesim çözüm söz konusu olabilir. Herhangi bir fikir/deneyim?

cevap

8

Şimdilik bloklarla devam edeceğim, bu oldukça basittir. Şimdi numaralandırmayı tercih ederim.

(doğru türü sağlanması) şey sayım için bir blok tipi:

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

MYRoot içinde ilgi serin listeleyicisi yöntemi (için koleksiyonlar maruz):

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

Yani istemci Şifrenin

: bazı düzgün makroyla

[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

Bunu yapmanın en iyi yolu, bence, dizi özellikleri için Temel Değer Kodlaması uyumlu yöntemlerini uygulamak olacaktır. Bu, koleksiyonlarınızı diğer nesneler tarafından gözlemlenebilir hale getirme ekledi. Bu konuda apple documentation numaralı telefondan okuyabilirsiniz. İşte MYRoot sınıfındaki Things dizisi için örnek bir uygulama. Her yöntemde kod kişiselleştirmek için çekinmeyin:

// 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]; 
} 

koleksiyonu üzerinde yineleme için yapardın aşağıdadır:

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

Yapabileceğin dizideki Şey eklemek için

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

Bu şekilde, @"things" özelliğine sahip tüm nesnelerin dizideki tüm değişikliklerden haberdar edileceğinden emin olursunuz. Ekleme yöntemlerini doğrudan çağırırsanız, bunu yapmayacaktır (bu, bazen kendi başına yararlıdır).

+0

Eğer işler bir dizilişse, o zaman KVO şeyleri olmadan basitçe (myRoot.things içindeki Thing * olayı) için yapılabilir. – Geri

+0

Fakat şeyler, childs adında bir diziye sahip olan bir varlıktır. Bu yüzden, bir kaç tıklamaya ihtiyacım var. – Geri

+0

Sorunun daha açık olması için modifiye ettim. Ya da en azından kesin. :) – Geri

İlgili konular