iOS for 和 forin 的区别 以及注意事项

一 效率:

for VS for(... in ...)

  1. for 的应用范围广基本可以NSArray、NSArray以及C语言的数组等,而for(... in ...)仅限于NSArray、NSArray等
  2. for(... in ...) 更简洁、效率更高

测试代码:

  10^7 的数组,时间单位 秒,精确度 毫秒

  1. NSMutableArray *test = [NSMutableArray array];
  2. for (int i= 0; i < 10000000; i++) {
  3. [test addObject:@(i)];
  4. }
  5. int sum = 0;
  6. double date_s = CFAbsoluteTimeGetCurrent();
  7. for (int i = 0;i < test.count; i++) {
  8. sum += 1;
  9. }
  10. double date_e =  CFAbsoluteTimeGetCurrent();
  11. NSLog(@"ForLoop Time: %f", date_e - date_s);
  12. date_s =  CFAbsoluteTimeGetCurrent();
  13. for (id obj in test) {
  14. sum += 1;
  15. }
  16. date_e =  CFAbsoluteTimeGetCurrent();
  17. 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.)的意思是:枚举的过程中数组发生了突变

时间: 2024-10-15 03:12:07

iOS for 和 forin 的区别 以及注意事项的相关文章

ios中@class和 #import区别

很多刚开始学习iOS开发的同学可能在看别人的代码的时候会发现有部分#import操作写在m文件中,而h文件仅仅使用@class进行声明,不禁纳闷起来,为什么不直接把#import放到h文件中呢?这 是因为h文件在修改后,所有import该h文件的所有文件必须重 新build,因此,如果把#import写在h文件中,import该h文件的文件也就会产生不必要的编译,增加编译时间,特别是在项目文件多的情况 下.想象一下,如果只是修改一个h文件而导致上百个文件不必要的编译,那是一件多么让人纠结的事情.

iOS 属性修饰符的区别

前言iOS5 之前 所有的 开发都需要开发者自己控制自己的对象的引用和释放.使用的修饰符是 assign.copy.retain iOS5 之后,Apple 推出了ARC(自动引用计数)机制,推出了新的修饰符替代之前的修饰符 strong.weak 简单说明1:ARC环境下,strong代替retain.weak代替assign2:weak的作用:在ARC环境下,,所有指向这个对象的weak指针都将被置为nil.这个T特性很有用,相信很多开发者都被指针指向已释放的对象所造成的EXC_BAD_AC

iOS load和initialize的区别

可能有些还不清楚load和initialize的区别,下面简单说一下: 首先说一下 + initialize 方法:苹果官方对这个方法有这样的一段描述:这个方法会在 第一次初始化这个类之前 被调用,我们用它来初始化静态变量. initialize方法的调用时机,当向该类发送第一个消息(一般是类消息首先调用,常见的是alloc)的时候,先调用类中的,再调用类别中的(类别中如果有重写):如果该类只是引用,没有调用,则不会执行initialize方法.两者方法的共同点:自动调用父类的,不需要super

iOS 开发----imageNamed和imageWithContentsOfFile区别

在 Apple 官方帮助文档提供了两个加载图片的方法 imageNamed , 其参数为图片的名字 imageWithContentsOfFile , 其参数是图片文件的路径 下面主要是说一下他们的区别: imageNamed: 用这个方法加载图片分为两种情况: 系统缓存有这个图片 直接从缓存中取得 系统缓存没有这个图片 通过传入的文件名对整个工程进行遍历 , 如果如果找到对应的图片 , iOS 系统首先要做的是将这个图片放到系统         缓存中去,以备下次使用的时候直接从系统缓存中取

IOS loadView 和 viewDidLoad 的区别

IOS 开发 loadView 和 viewDidLoad 的区别 iPhone开发必不可少的要用到这两个方法. 他们都可以用来在视图载入的时候,初始化一些内容. 但是他们有什么区别呢? viewDidLoad 此方法只有当view从nib文件初始化的时候才被调用. loadView 此方法在控制器的view为nil的时候被调用. 此方法用于以编程的方式创建view的时候用到. 如: - ( void ) loadView { UIView *view = [ [ UIView alloc] i

ios nil null Nil NSNull区别

nil.Nil.NULL.NSNull的区别 nil:指向一个对象的空指针 Nil:指向一个类的空指针 NULL:指向其他类型(如:基本类型.C类型)的空指针 NSNull:通常表示集合中的空值 举例: NSURL *url = nil; Class class = Nil; int *pointerInt = NULL; NSArray *array = [NSArray arrayWithObjects:[[NSObject alloc] init], [NSNull null], [[NS

iOS开发-NSOperation与GCD区别

Mac OS X 10.6及iOS4.0之后导入了可以使全体线程更高效运行,并且使并行处理应用更易开发的架构,GCD(Grand Central  Dispatch),同时引入的还有Run Loop,线程(包括Cocoa和POSIX)和Operation.GCD拥有非常轻量级的工作单元和并发方式,并且由系统决定其最佳调度方式.这个时候出现了一个问题,NSOperation如何处理呢? 其实我们在通过NSOperation和GCD进行开发过程中,会发现两者执行的方式有许多相似之处,NSOperat

IOS bounds 与 frame的区别

今天写案例代码,发现资料上设置一个UIButton的frame时,是这样设置的 btnCover.frame = self.view.bounds; 但是我自己一开始是这样写的 btnCover.frame = self.view.frame; 后来,我发现,两个不同的写法都达到了我想要的想过,也就是UIButton的大小和父容器的大小一致,我就纳闷了,既然是同样的效果,为什么即有bounds又有frame.后来经查,发现如下区别: -(CGRect)frame{ return CGRectMa

ios 通知和代理的区别

区别一:delegate针对one-to-one关系,并且reciever可以返回值给sender:notification 可以针对one-to-one/many/none,reciever无法返回值给sender:所以,delegate用于sender希望接受到reciever的某个功能反馈值,notification用于通知多个object某个事件. 区别二: Delegate:消息的发送者(sender)告知接收者(receiver)某个事件将要发生,delegate同意然后发送者响应事