2010-06-14 30 views
18

Tôi có các trẻ em NSMutableArray * trong tầng lớp cơ sở hạ tầng "Foo" là siêu lớp của nhiều lớp khác, như "Bar1" và "Bar2". Mảng đó lưu trữ các đối tượng Bar1 và Bar2 để có được cấu trúc cha-con đệ quy giống như con của các lớp con từ Foo. Để truy cập vào các đối tượng trong mảng, tôi vòng qua chúng bằng cách sử dụng vòng lặp foreach trong Objective-C:Objective-C NSMutableArray - vòng lặp foreach với các đối tượng của nhiều lớp

for(Foo *aFoo in children) { 
    ... 
} 

Nhưng thường thì tôi chỉ cần để lặp qua các đối tượng trong mảng đó có một lớp học nào đó, trong này trường hợp tôi muốn thực hiện một nhiệm vụ cho từng đối tượng của lớp Bar1 trong mảng con. Sử dụng cho (Bar1 * anObject ở trẻ em) một lần nữa lặp qua tất cả các đối tượng và không chỉ những người có lớp Bar1. Có cách nào để đạt được những gì tôi cần không?

Trả lời

40

Bạn phải lặp qua tất cả các đối tượng và thực hiện kiểm tra loại bên trong vòng lặp.

for(id aFoo in children) { 
    if ([aFoo isKindOfClass:[Bar1 class]]) 
     ... 
    } 
} 
+1

điều này có thể khá tốn kém về bộ nhớ nhưng dường như không có cách nào khác. Cảm ơn bạn –

+5

không, nó không thay đổi bộ nhớ của bạn, bạn chỉ đọc những gì đã có trong bộ nhớ – unbeli

+3

Nói chung, nếu bạn cần sử dụng 'isKindOfClass:' để phân biệt giữa các lớp trong một bộ sưu tập, mẫu thiết kế của bạn nằm ngoài tiêu chuẩn. Điều này đặc biệt đúng nếu bộ sưu tập của bạn chứa các phiên bản của các lớp hoàn toàn trong quá trình tạo của bạn. – bbum

9

Bạn có thể làm một cái gì đó như thế này:

NSPredicate* bar1Predicate = [NSPredicate predicateWithFormat:@"SELF.class == %@", [Bar1 class]]; 
NSArray* bar1z = [children filteredArrayUsingPredicate:bar1Predicate]; 
for(Bar1* bar in children) { 
    // do something great 
} 

Điều quan trọng cần lưu ý, tuy nhiên, điều này sẽ không làm việc với nhiều lớp Cocoa tiêu chuẩn như NSString, NSNumber, vv mà sử dụng các cụm lớp hoặc các lớp triển khai đặc biệt (ví dụ: bất kỳ thứ gì được miễn phí cầu nối với loại CoreFoundation) vì các lớp sẽ không khớp chính xác. Tuy nhiên, điều này sẽ làm việc với các lớp bạn xác định miễn là lớp thực sự là một thể hiện của Bar1.

Lưu ý nhấn mạnh: Người dùng @Alex đề xuất rằng có thể không rõ ràng rằng các lớp phải khớp chính xác với ghi chú của tôi ở trên, vì vậy tôi đang nghỉ lại điều đó. Các lớp phải khớp chính xác để bộ lọc này hoạt động, vì vậy nếu bạn phân lớp Bar1 hoặc cung cấp một số lớp proxy, bạn sẽ phải điều chỉnh bộ lọc để các lớp đó được đưa vào. Theo văn bản, chỉ phiên bản Bar1 sẽ được trả lại trong mảng được lọc.

+0

cũng có, tôi nghĩ rằng điều này là không có sẵn trên iPhone – unbeli

+2

@unbeli: Nó hoàn toàn có sẵn trên iPhone, không phải là OP đã đề cập đến iPhone ở tất cả. –

+0

Nhưng, nếu bạn bao giờ phân lớp 'Bar1', mã này sẽ không khớp với các đối tượng của lớp con. OP không nói gì về các lớp con, nhưng điều quan trọng cần lưu ý. – Alex

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