A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© jingkai 中级黑马   /  2015-5-19 09:40  /  1236 人查看  /  9 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

老师在遍历的时候用了三种方式,可是除了第一种for循环外
其他两种我都迷迷糊糊的 不知所云
第二种是这样的
int i = 0;
for(id obj in array)
{
      NSUInter i = [array indexOfObject : obj];

NSLog(@"%@-%ld",i,obj);

}
我想要问的的时 for循环中的 id obj in array是什么意思,另外循环的机理是什么。还有就是 i放在循环体中定义或者换成i++行么?

9 个回复

倒序浏览
id obj 是指数组中的元素。这是固定的写法。你记住就行了
回复 使用道具 举报
id obj in array 的意思就是,循环取出array中的值并且赋值给obj,id是取出的值得类型,这个JavaScript语法一样的,java中也有类似的,,id obj : array。我感觉,最根本的都是for循环,也就是可能就是for循环又包了一层。放循环体定义,那就是每次循环都定义一个变量,并且分配内存,多耗性能。
所以最好,在面外定义,里面只修改值就行了。
回复 使用道具 举报
你就看成for(i in (1...20) )
i对应的是id obj  1...20 对应的是arry数组 循环的时候 第一次i=1 第二次i=2,  i每次的数值都是in后面的数值
回复 使用道具 举报
这么说,id obj这个就是每次从数组中取出来的元素,如果你的数组中元素类型一样的话,比如都是Student类型,你可以把id obj 改成Student *stu,这样,你在循环中可以直接使用Student类型中的属性和方法了。
第三种不知道你指的是不是这种:
  1. array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
  2.         //你的方法
  3.     }
复制代码

这个中,id obj和上面说的概念一样,可以自己修改,idx是当前元素的索引,不需要自己再指定,最后那个是控制循环停止的标识
回复 使用道具 举报
cogddo 发表于 2015-5-19 10:03
id obj in array 的意思就是,循环取出array中的值并且赋值给obj,id是取出的值得类型,这个JavaScript语法 ...

我看到哥们的说法,觉得那个耗费资源的说法不太可信,专门去做了一个实验。实验可能不太专业,但是应该可以说明,forin没有比for耗费更多资源。
请注意左上角的内存使用情况,第一张是用for循环,第二张用的forin。
     


另附数组自带的循环方法。


回复 使用道具 举报
cogddo 中级黑马 2015-5-19 10:38:33
7#
mony 发表于 2015-5-19 10:30
我看到哥们的说法,觉得那个耗费资源的说法不太可信,专门去做了一个实验。实验可能不太专业,但是应该可 ...

for和for in耗资源我没比较过,,可能你没看清楚,我说的耗资源是在循环里定义变量。
回复 使用道具 举报
cogddo 发表于 2015-5-19 10:03
id obj in array 的意思就是,循环取出array中的值并且赋值给obj,id是取出的值得类型,这个JavaScript语法 ...

虽然没有学过java但是你说的还是有点清楚的 谢谢
回复 使用道具 举报
mony 发表于 2015-5-19 10:30
我看到哥们的说法,觉得那个耗费资源的说法不太可信,专门去做了一个实验。实验可能不太专业,但是应该可 ...

其实我想听听你总结的结论 新人 有点看不懂
回复 使用道具 举报
本帖最后由 kailee 于 2015-5-19 16:41 编辑

(一)楼主提到的第二种方法是快速遍历:
1.obj代表着数组中的每一个元素(id类型)
2.数组中的每一个元素拿出来赋值给obj,赋值一次调用一次循环体

  1. for (id obj in array)
  2. {
  3.         // 找出obj在数组中的位置,i记录位置
  4.         NSUInterger i = [array indexOfObject:obj];
  5.         NSLog(@"%ld-%@", i, obj);
  6. }
复制代码


(二)第三种方式调用Array的enumerateObjectsUsingBlock方法分析:
1.每拿到一个元素就调用一次block,就是把元素传递给block
2.每遍历到一个元素,就会调用一次block
3.并且当前元素和索引位置当做参数传递给block
4.BOOL *stop 用来停止遍历,
   
  1.    [array enumerateObjectsUsingBlock:^(id obj, NSUInterger idx, BOOL *stop)
  2.                 {
  3.                         NSLog(@"%ld-%@", idx, obj);
  4.                         // 遍历到1就退出循环
  5.                         if (idx == 1)
  6.                         {
  7.                                 // 遍历停止
  8.                                 *stop = YES;
  9.                         }
  10.                 }];
复制代码


5.block遍历的本质:

  1. void ^(myblock)(id, NSUInterger, BOOL *) = ^(id obj, NSUInterger idx, BOOL *stop)
  2. {
  3.         NSLog(@"%ld-%@", idx, obj);
  4.         if (idx == 1)
  5.         {
  6.                 // 遍历停止
  7.                 *stop = YES;
  8.         }
  9. };

  10. for (int i = 0; i < array.conut; i++)
  11. {
  12.         // 用来标记是否需要停止遍历
  13.         BOOL isStop = NO;
  14.         // 取出元素
  15.         id obj = array;
  16.         // 把BOOL的地址传递给myblock,否则就变成了“值传递”,那么
  17.         // myblock就无法改变BOOL的值,那么for里边BOOL的值一直就是NO无法修改
  18.         myblock(obj, i, &isStop);

  19.         if (isStop)
  20.         {
  21.                 break;
  22.         }
  23. }
复制代码



回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马