2011-11-13 36 views

Trả lời

62

Nhìn vào API cho NSArray và bạn sẽ thấy những phương pháp

- (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block 

Vì vậy, cho rằng một trong một thử

[savedArray enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 

    //... Do your usual stuff here 

    obj // This is the current object 
    idx // This is the index of the current object 
    stop // Set this to true if you want to stop 

}]; 
+10

để thêm - cờ dừng được sử dụng bằng cách gọi '* stop = YES' (chỉ đơn giản là' stop = YES' không hoạt động) – Tim

+2

tôi tự hỏi, nếu đây là nhanh hơn, chỉ cần thêm một số nguyên chỉ số –

9

Tôi cho rằng giải pháp cùn nhất để điều này sẽ chỉ đơn giản là tăng một chỉ số bằng tay.

NSUInteger indexInSavedArray = 0; 
for (MyClass *entry in savedArray) { 
    indexInSavedArray++; 
} 

Ngoài ra, bạn không thể sử dụng liệt kê nhanh.

for (NSUInteger indexInSavedArray = 0; indexInSavedArray < savedArray.count; indexInSavedArray++) { 
     [savedArray objectAtIndex:indexInSavedArray]; 
    } 
+5

Ngoài ra ông có thể sử dụng '[savedArray indexOfObject: entry];' :) –

+6

Vâng, đó sẽ làm việc, mặc dù nó sẽ rất hiệu quả vì nó sẽ phải gửi isEqual cho mọi đối tượng dẫn đến các đối tượng phù hợp . Ví dụ: sẽ mất 500 thông báo isEqual gửi (và tính toán nếu đối tượng thực sự thực hiện điều gì đó trong thực tế trong isEqual) để lấy chỉ mục của phần tử thứ 500 và sau đó thêm 501 thông báo sẽ gửi để nhận đối tượng tiếp theo sau đó. chỉnh sửa: có lẽ bạn đang châm biếm và tôi bỏ lỡ một trò đùa :) –

7

Câu hỏi này đã được trả lời, nhưng tôi nghĩ tôi sẽ thêm rằng các lần lặp đếm thực sự là kỹ thuật được đề cập trong tài liệu Thư viện dành cho nhà phát triển iOS:

NSArray *array = <#Get an array#>; 
NSUInteger index = 0; 

for (id element in array) { 
    NSLog(@"Element at index %u is: %@", index, element); 
    index++; 
} 

Tôi chắc chắn sẽ có một mẹo lạ mắt, nhưng tôi đoán là không. :)

+1

Cách của Apple là không an toàn và IMHO phải tránh được - nó sai lầm khủng khiếp khi ai đó ngây thơ thêm "ngắt" hoặc "tiếp tục" vào mã của bạn. Đáng buồn thay, thiết kế của họ cho Fast Enumeration không phải là rất tốt. – Adam

+0

Bạn có ý nghĩa gì đó sai nếu "ngắt" hoặc "tiếp tục" được đặt bên trong mã liệt kê nhanh không? Apple đã làm điều gì đó khác hơn, C#? Chỉ cần yêu cầu giáo dục của riêng tôi (và tránh các lỗi trong tương lai). Cảm ơn! – GrandAdmiral

+3

Ví dụ đơn giản: mã ví dụ dài 2 dòng. Nếu nó dài 20 dòng, và tại dòng 5, ai đó sẽ thêm "tiếp tục"? Việc tiếp tục sẽ làm cho "phần tử" tiến lên - nhưng không phải là "chỉ mục". Aha! Vì vậy, bạn đặt chỉ mụC++ ngay từ đầu, ngay sau điểm được sử dụng. Nhưng nếu ai đó sau đó cố gắng tham khảo nó sau này trong cơ thể vòng lặp? Bây giờ nó quá lớn bằng 1. ... vv – Adam

0

Quan sát đơn giản: Nếu bạn khởi tạo chỉ mục thành -1 và sau đó đặt chỉ mụC++ làm dòng đầu tiên trong vòng lặp, không bao gồm tất cả các cơ sở (miễn là ai đó không trượt mã trong phía trước của gia số)?

+1

"miễn là ai đó không trượt mã trước chữ" Mã hóa dựa trên đức tin ở mức tốt nhất của nó – Tim

3

Nếu bạn muốn truy cập chỉ mục hoặc trả lại khối bên ngoài ở đây là một đoạn mã có thể hữu ích. (xem xét mảng là một mảng của NSString).

- (NSInteger) findElemenent:(NSString *)key inArray:(NSArray *)array 
{ 
    __block NSInteger index = -1; 
    [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 
     if ([obj isEqualToString:key]) { 
      *stop = YES; 
      index = idx; 
     } 
    }]; 
    return index; 
} 
Các vấn đề liên quan