2011-12-14 24 views
34

những ưu điểm và nhược điểm của hai phương pháp sau đây là gì:Enumerate Objective-CUsingBlock và liệt kê nhanh?

enumerateUsingBlock

NSArray *myArray = [[NSArray alloc] init]; 
[myArray enumerateObjectsUsingBlock:^(id anObject, NSUInteger idx, BOOL *stop) { 
    if (anObject == someOtherObject) { 
     [anObject doSomething:idx]; 
     *stop = YES; 
    } 
}]; 

liệt kê nhanh suy nghĩ

NSArray *myArray = [[NSArray alloc] init]; 
int idx = 0 
for (id anObject in myArray) { 
    if (anObject == someOtherObject) { 
     [anObject doSomething:idx]; 
     break; 
    } 
    ++idx; 
} 
+2

Just FYI, cả IFS có lỗi chính tả xấu - nó phải được == thay vì = –

+0

trùng lặp có thể xảy ra của [Khi sử dụng enumerateObjectsUsingBlock vs cho] (http: // stackoverflow.com/questions/4486622/when-to-use-enumerateobjectsusingblock-vs-for) –

Trả lời

47

This blog post bao gồm sự khác biệt lớn. Nói tóm lại:

  • nhanh liệt kê hiện có sẵn trên OS X 10.5+ khối có sẵn trên 10.6+
  • Đối liệt kê đơn giản, nhanh chóng liệt kê là một chút nhanh hơn so với khối dựa trên liệt kê
  • Nó dễ dàng hơn (và hoạt động tốt hơn) để liệt kê đồng thời hoặc ngược lại với liệt kê theo khối với số đếm nhanh
  • Khi đếm trên NSDictionary bạn có thể nhận được khóa và giá trị trong một lần truy cập với điều tra dựa trên khối, trong khi có liệt kê nhanh bạn phải sử dụng chìa khóa để lấy giá trị trong một tin nhắn riêng biệt gửi.

Về điểm cuối cùng (NSDictionary liệt kê), so sánh này:

for (id key in dictionary) 
{ 
    id obj = [dictionary objectForKey: key]; 
    // do something with key and obj 
} 

này:

[dictionary enumerateKeysAndObjectsUsingBlock: ^(id key, id obj, BOOL *stop) { 
    // do something with key and obj 
}]; 

Bên cạnh đó, cả hai phương pháp bảo vệ các bộ sưu tập có thể thay đổi từ đột biến bên trong vòng lặp liệt kê. Thật thú vị, nếu bạn cố gắng biến đổi bộ sưu tập bên trong một liệt kê dựa trên khối, bạn sẽ nhận được một ngoại lệ được đưa ra bởi __NSFastEnumerationMutationHandler của CoreFoundation, gợi ý rằng có một số mã phổ biến nằm dưới mui xe.

NSMutableArray *myArray = [NSMutableArray arrayWithObjects:@"a", @"b", nil]; 
[myArray enumerateObjectsUsingBlock:^(id anObject, NSUInteger idx, BOOL *stop) { 
    // Attempt to mutate the array during enumeration 
    [myArray addObject:@"c"]; 
}]; 

Output:

2011-12-14 22:37:53.716 Untitled[5809:707] *** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x109614190> was mutated while being enumerated.' 
*** First throw call stack: 
(
    0 CoreFoundation      0x00007fff8cca7286 __exceptionPreprocess + 198 
    1 libobjc.A.dylib      0x00007fff8319ad5e objc_exception_throw + 43 
    2 CoreFoundation      0x00007fff8cd311dc __NSFastEnumerationMutationHandler + 172 
    3 CoreFoundation      0x00007fff8cc9efb4 __NSArrayEnumerate + 612 
    4 Untitled       0x00000001094efcea main + 250 
    5 Untitled       0x00000001094efbe4 start + 52 
    6 ???         0x0000000000000001 0x0 + 1 
) 
terminate called throwing an exceptionRun Command: line 1: 5809 Abort trap: 6   ./"$2" 
+0

Để lại hiệu suất sang một bên, phiên bản nào bạn thấy dễ đọc hơn ngay cái nhìn đầu tiên? –

+1

@rsanchezsaez Câu hỏi thú vị! Tôi tìm thấy một vòng lặp 'for' trên các phím từ điển dễ đọc hơn. Cú pháp khối vẫn không trực quan với tôi. –

+0

cho giá trị khóa, tôi thấy khối trực quan hơn (tôi đến từ C (++) và chỉ sử dụng khối một lần) –

4

đầu tiên mà tôi suy nghĩ của tôi

  • Các khối có sẵn trong iOS 4 trở lên vì vậy nếu bạn cần hỗ trợ các phiên bản cũ hơn thì bạn không thể sử dụng cú pháp khối.

  • Chúng khá tương đương về những gì chúng làm ngoài việc bạn không thể vô tình làm hỏng bộ đếm trong phiên bản khối.

  • Một khác biệt tiềm năng khác là bạn có thể xác định khối ở nơi khác và chuyển vào các khối khác nhau tùy thuộc vào tiểu bang của bạn.

Hy vọng rằng đây chỉ là một ví dụ rất thô như trong đoạn mã là khá nghèo và có những cách hiệu quả hơn để làm điều này;)

+0

Ngoài ra, nếu tôi nhớ lại chính xác, nó đã được nêu trong một video WWDC 2010 chặn liệt kê thậm chí còn hiệu quả hơn đếm nhanh. –

+1

Đó là vấn đề với các video bạn biết có những thứ tốt trong đó nhưng may mắn tìm lại nó vào một ngày sau đó. Tôi đã xem các tài liệu cho [Liệt kê: Traversing Elements's Collection] (http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Collections/Articles/Enumerators.html) và không có nổi bật đề cập đến sự gia tăng hiệu suất: S –

+2

Thực ra, tôi đã tìm thấy nó. Đó là video "Có gì mới trong nền tảng cho iOS 4" từ năm 2010. –

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