Mặc dù câu hỏi này đã cũ, mọi thứ vẫn không thay đổi, câu trả lời được chấp nhận là không chính xác.
Các enumerateObjectsUsingBlock
API không có nghĩa là để thay thế for-in
, nhưng đối với một trường hợp sử dụng hoàn toàn khác nhau:
- Nó cho phép áp dụng logic tùy ý, không cục bộ. tức là bạn không cần biết khối này làm gì để sử dụng nó trên một mảng.
- Liệt kê đồng thời cho các bộ sưu tập lớn hoặc tính toán nặng (sử dụng
withOptions:
tham số)
Bảng liệt kê nhanh for-in
vẫn là thành ngữ phương pháp để liệt kê một bộ sưu tập.
Lợi ích liệt kê nhanh từ tính ngắn gọn của mã, khả năng đọc và tối ưu hóa bổ sung làm cho nó nhanh một cách bất thường. Nhanh hơn một vòng lặp C cũ!
Một thử nghiệm nhanh kết luận rằng trong năm 2014 trên iOS 7, enumerateObjectsUsingBlock
tốc độ chậm hơn 700% so với for-in (dựa trên các lần lặp 1mm của một mảng 100 mục).
Là hiệu suất thực sự là một mối quan tâm thực tế ở đây?
Chắc chắn là không, với ngoại lệ hiếm.
Vấn đề là chứng minh rằng có rất ít lợi ích khi sử dụng enumerateObjectsUsingBlock:
hơnfor-in
mà không có một lý do thực sự tốt. Nó không làm cho mã dễ đọc hơn ... hoặc nhanh hơn ... hoặc an toàn cho chuỗi. (một quan niệm sai lầm phổ biến khác).
Sự lựa chọn đi xuống sở thích cá nhân. Đối với tôi, tùy chọn thành ngữ và dễ đọc chiến thắng. Trong trường hợp này, đó là liệt kê nhanh bằng cách sử dụng for-in
.
Điểm chuẩn:
NSMutableArray *arr = [NSMutableArray array];
for (int i = 0; i < 100; i++) {
arr[i] = [NSString stringWithFormat:@"%d", i];
}
int i;
__block NSUInteger length;
i = 1000 * 1000;
uint64_t a1 = mach_absolute_time();
while (--i > 0) {
for (NSString *s in arr) {
length = s.length;
}
}
NSLog(@"For-in %llu", mach_absolute_time()-a1);
i = 1000 * 1000;
uint64_t b1 = mach_absolute_time();
while (--i > 0) {
[arr enumerateObjectsUsingBlock:^(NSString *s, NSUInteger idx, BOOL *stop) {
length = s.length;
}];
}
NSLog(@"Enum %llu", mach_absolute_time()-b1);
Các kết quả:
2014-06-11 14:37:47.717 Test[57483:60b] For-in 1087754062
2014-06-11 14:37:55.492 Test[57483:60b] Enum 7775447746