2012-09-23 22 views
8

Tôi có một lớp mô hình với một số tác phẩm đối tượng và tôi không biết cách tốt nhất để viết trình lặp cho việc này. Để xem các vấn đề chi tiết hơn, đây là hệ thống phân cấp (mã bán giả):Làm cách nào để viết trình vòng lặp của riêng tôi cho thuộc tính bộ sưu tập của thuộc tính (với kiểu nhập chính xác)?

Một lớp Root:

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

Một số lớp con cụ thể:

MYConcreteStuff : MYEntity 
@property int number; 

MYConcreteThing : MYEntity 
@property NSString *string; 

Và một đối tượng gốc với bộ sưu tập bê tông:

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

Bây giờ tôi có thể viết trình truy cập thành viên mát mẻ cho bộ sưu tập (trong MYEn tity), như:

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

    return nil;  
} 

Và thậm chí nhiều bộ phận truy cập thành viên được đúc tốt hơn cho đối tượng gốc.

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

    return nil;  
} 

Nhưng tôi không biết cách viết một số trình vòng lặp trên mạng cho các bộ sưu tập đó. Mã Wannabe khách hàng là một cái gì đó như:

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

Tôi đang nghĩ đến việc sử dụng các khối, nhưng có thể là một giải pháp cắt sạch hơn. Bất kỳ ý tưởng/kinh nghiệm nào?

Trả lời

8

Tôi sẽ tiếp tục với các khối ngay bây giờ, điều đó khá đơn giản. Bây giờ tôi thích thuật ngữ liệt kê.

Một loại khối cho điều enumaration (đảm bảo đúng loại):

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

Một phương pháp điều tra viên mát mẻ cho Mọi thứ trong MYRoot (không phơi bày bộ sưu tập):

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

Vì vậy, mã khách hàng đi:

[myRoot enumerateThings:^(MYThing *eachThing) 
{ 
    NSLog(@"Thing: %@", eachThing.string);   
}]; 

Với một số macro gọn gàng:

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

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

Cách tốt nhất để làm điều này, theo ý kiến ​​của tôi, sẽ là triển khai các phương pháp tuân thủ Mã hóa giá trị khóa cho thuộc tính mảng. Điều này sẽ có thêm tiền thưởng làm cho bộ sưu tập của bạn có thể quan sát được bởi các đối tượng khác. Bạn có thể đọc tất cả về nó trong apple documentation. Đây là một ví dụ thực hiện cho mảng Things trong lớp MYRoot. Cảm thấy tự do để cá nhân mã trong mỗi phương pháp:

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

Để lặp qua các bộ sưu tập bạn sẽ làm như sau:

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

Để thêm một Thing trong mảng bạn có thể làm

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

Khi thực hiện theo cách này, bạn đảm bảo rằng tất cả đối tượng quan sát thuộc tính @"things" sẽ được thông báo về tất cả các thay đổi đối với mảng. Nếu bạn gọi phương thức chèn trực tiếp thì chúng sẽ không (điều này đôi khi hữu ích theo cách riêng của nó).

+0

Nếu mọi thứ là một mảng, sau đó nó có thể được thực hiện đơn giản bởi (Điều * điều trong myRoot.things), không có công cụ KVO. – Geri

+0

Nhưng mọi thứ là một thực thể có một mảng được gọi là Childs. Đó là lý do tại sao tôi cần một số indirection. – Geri

+0

Tôi đã sửa đổi câu hỏi để rõ ràng hơn. Hoặc chính xác ít nhất. :) – Geri

Các vấn đề liên quan