一 效率:
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 的操作较多些。
二 所用的区别
for循环主要用在你已经知道了循环的次数或者可以明确的得到的循环次数
比如你要在屏幕上打出100个"hello word!" 或者 循环某个数组中的全部内容
那么就可以用for (int i=0;i<100,i++) for (int i = 0; i < array.count; i ++)
这里你已经很明确了是100 或者得到的array的数组个数
for in循环主要是方便遍历已经知道对象类型的数组
同时不关心索引的情况
比如已经知道数组里都是uibutton
那么你就可以直接用
for uibutton *tmpbutton in array
这样你就可以直接通过tmpbutton直接访问数组里的每一个button
另外数组还有一种用block遍历的方法
1 [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { 2 //..... 3 }];
这种方法有一个要注意的地方就是可能会有异步执行的问题
最后这三种遍历方式是for in的效率是最高的
--------------------------------------------------------------------------------------------
for in 循环遍历比for更高级一些,当你数组里面的元素对象都一样,就可以用for in进行遍历,进行接受的对象跟数组里面所存储的是同一种类型
三 注意事项
如果在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.)的意思是:枚举的过程中数组发生了突变