一 效率:
for VS for(... in ...)
- for 的應用范圍廣基本可以NSArray、NSArray以及C語言的數組等,而for(... in ...)僅限於NSArray、NSArray等
- for(... in ...) 更簡潔、效率更高
測試代碼:
10^7 的數組,時間單位 秒,精確度 毫秒
- NSMutableArray *test = [NSMutableArray array];
- for (int i= 0; i < 10000000; i++) {
- [test addObject:@(i)];
- }
- int sum = 0;
- double date_s = CFAbsoluteTimeGetCurrent();
- for (int i = 0;i < test.count; i++) {
- sum += 1;
- }
- double date_e = CFAbsoluteTimeGetCurrent();
- NSLog(@"ForLoop Time: %f", date_e - date_s);
- date_s = CFAbsoluteTimeGetCurrent();
- for (id obj in test) {
- sum += 1;
- }
- date_e = CFAbsoluteTimeGetCurrent();
- NSLog(@"Enumeration Time: %f", date_e - date_s);
測試結果:
考慮到實際情況,ForLoop 的操作較多些。
1 [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 2 //..... 3 }];
如果在for in 循環里,對這個數組進行了修改的話,無論是增,刪,修改數組元素位置,都會扔一個異常出來,錯誤是被遍歷的數組已被銷毀(<__NSArrayM: 0xa4fc000> was mutated while being enumerated.),比如以下代碼:
NSMutableArray* arr = [NSMutableArray arrayWithObjects:@"1",@"2",@"3", nil];
for (NSString* str in arr) {
if ([str isEqualToString:@"1"] || [str isEqualToString:@"5"]) {
[arr addObject:@"4"]; //或者 [arr removeObject:@"1"]; 或者 [arr exchangeObjectAtIndex:0 withObjectAtIndex:2];
continue;
}
}
原因:
for in實際上是快速枚舉,跟for循環意義上還是有區別的。
NSArray的枚舉操作中有一條需要注意:對於可變數組進行枚舉操作時,你不能通過添加或刪除對象這類操作來改變數組容器。如果你這么做了,枚舉器會很困惑,而你將得到未定義的結果。
而本身這種操作也是有問題的,數組容器已經改變,可能遍歷到沒有分配的位置,用for循環機器不能自己察覺,但是枚舉器可以察覺。
追加,這個錯誤(<__NSArrayM: 0xa4fc000> was mutated while being enumerated.)的意思是:枚舉的過程中數組發生了突變