【NSArray数组的遍历 Objective-C语言】

本文详细介绍了Objective-C中NSArray数组的三种遍历方式:1) 使用for循环,通过下标访问元素;2) 使用增强for循环(for-in),直接遍历元素;3) 使用enumerateObjectsUsingBlock方法,结合Block处理每个元素。文章通过实例代码解释了每种遍历方式的执行原理,并特别提到了当数组中元素类型不一致时,建议使用id类型作为迭代变量。

一、NSArray数组的遍历

1.那NSArray数组是怎么遍历的呢,你想到了几种方式

1)是不是for循环啊

所以,第一种方式,使用for循环来遍历数组中的每一个元素

例如,我有一个数组

NSArray *arr = @[@“jack”,@“rose”,@“lili”,@“jack”,@“rose”,@“lili”];

//来个for循环

for(int i = 0;i<arr.count;i++)

{

NSLog(@“%@”,arr[i]);

}

输出:jack

rose

lili

jack

rose

lili

是不是这样就能拿到数组中的每一个元素的值吧

当然,这句话你也可以换成那个方法,objectAtIndex

NSLog(@“%@”,[arr objectAtIndex:i]);

原理:将下标挨个挨个遍历出来,然后取值

2.第二种方式,使用增强for循环,来遍历NSArray数组中的元素

for(NSString *str in arr)

{

NSLog(@“%@”,str);

}

输出:jack

rose

lili

jack

rose

lili

1)语法格式:

一个for(

for(里面写什么呢

for(先写个元素类型 然后再写个变量名 in 数组名)

{

直接通过变量名就可以拿到数组中的每一个元素

}

现在我要遍历一下这个数组:

NSArray *arr = @[@“jack”,@“rose”,@“lili”,@“jack”,@“rose”,@“lili”];

请问这个数组里面每一个元素是什么类型的

是不是NSString类型的啊

所以,for(NSString *

是不是啊

然后再来个变量名,是不是取个变量名就可以了吧,来个str

for(NSString *str

第三个,in,这是固定的

for(NSString *str in

最后,数组名,哪个数组名,是不是arr数组名

好,搞定啊

for(NSString *str in arr)

//好,在这个循环体的里面,通过这个变量名,通过这个str,就可以拿到每个元素的值

{

NSLog(@“%@”,str);

}

其实这句话NSString *str,是在声明一个变量

这个变量,我们叫做迭代变量

声明在for()中的变量,我们叫迭代变量

for in循环,也叫增强的for循环,它的执行原理:

将这个arr数组中的每一个元素,从第一个到最后一个,挨个挨个的赋值给这个迭代变量,然后执行循环体

例如,下面这个数组:

NSArray *arr = @[@“jack”,@“rose”,@“lili”];

for(NSString *str in arr)

{NSLog(@“%@”,str);}

执行这个循环的时候

先把这个数组里面第一个元素赋给这个迭代变量

然后,执行循环体

执行完了之后呢,再把这个数组里面第二个元素,赋给这个迭代变量,再执行循环体

再把第三个元素赋给这个迭代变量,再执行循环体

好了,是不是所有元素都赋过值了啊

自动结束循环

执行的原理:

将数组中的第1个元素的值,赋值给迭代变量,执行循环体

再将数组中的第2个元素的值,赋值给迭代变量,再执行循环体

再将数组中的第3个元素的值,赋值给迭代变量,再执行循环体

再将数组中的最后1个元素的值赋值给迭代变量,执行循环体

结束循环

4)语法总结:

一般情况下,这个迭代变量的类型,是和数组中存储的数据类型保持一致

这个数组中的元素是什么类型的,那么你这儿就写什么类型的

数组中的元素是不是字符串类型的啊,你这个迭代变量,你就把它声明成字符串类型的就可以了

所以,第一个点

a.迭代变量的类型和数组中的元素的类型保持一致

b.迭代变量的名字是不是只能是str,不是,既然是个变量,所以名称随意

c.in是固定的

d.遍历哪1个数组,就将这个数组写在in后面

e.循环体里面,迭代变量的值,直接就是元素的值

2.好,我换一个啊,例如:

Person *p1 = [Person new];

Person *p2 = [Person new];

Person *p3 = [Person new];

Person *p4 = [Person new];

Person *p5 = [Person new];

NSArray *arr = @[p1,p2,p3,p4,p5];

好了,我想问一个问题,这个时候,我想要用增强for循环来遍历这个arr数组,怎么做

for(Person *per in arr)

{

NSLog(@“%@”,per);

}

5.但是,有一种情况很尴尬,例如:

NSArray *arr = @[p1,p2,p3,@“jack”,@“rose”,@“lili”];

我们这个数组里,可以既存Person对象,又存NSString对象啊,

可以,因为我们说过

这个数组里面是不是可以存任意的OC对象啊

这是不是OC对象啊,是的

那这儿有个问题了,我遍历的时候,我是用什么类型的迭代变量呢

用id类型的

如果数组里面的类型不一致,存储在数组里面的元素类型不一致,那这个时候,建议大家使用id去遍历

NSArray *arr = @[p1,p2,p3,p4,p5,@“jack”,@“rose”,@“lili”];

for(id item in arr)

{

NSLog(@“%@”,item);

}

当NSArray数组中存储的数据的类型不一致的时候,

迭代变量的类型建议使用id类型

三、第三种遍历NSArray数组的方式,使用block遍历

1.例如,我有一个NSArray数组:

NSArray *arr = @[@“jack”,@“rose”,@“Jim”];

这时候,arr有一个方法,叫做enumerateObjectsUsingBlock:^(id Nonnull obj,NSUInteger idx,BOOL * _Nonnull stop){code}

这个时候,要干嘛,是不是要传1个block代码段进去啊

不管三七二十一,怎么办,回车

让它自动生成这个代码段儿吧

这个方法的签名如下:

- (void)enumerateObjectsUsingBlock:(void (^)(ObjectType obj),NSUInteger idx,BOOL *stop))block;

这是一个方法,记住,这个方法做什么事情,这个方法内部做什么事情,很简单,遍历数组当中的每一个元素,

这是1个方法,这个方法的作用就是来遍历数组中的每1个元素

它把每1个元素遍历出来以后,这个元素怎么去处理呢

它是不是让我自己写代码来处理

你看,传了三个参数

^(id _Nonnull obj,NSUInteger idx,BOOL *stop){code};

第一个是obj,第二个是idx,第三个是stop

主要看这个obj

这个obj就是它遍历出来的每1个元素值

你看啊

NSLog(@“%@”,obj);

输出:jack

rose

Jim

也就是这段代码,

NSArray *arr = @[@“jack”,@“rose”,@“jim”];

[arr enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {

NSLog(@“%@”,obj);

}];

输出的是:jack

rose

Jim

首先,arr是个对象,对不对

这个数组对象里面是不是有三个元素啊

一个是jack,一个是rose,一个是Jim

这个enumerate,你先不要去管那个参数好不好,这个时候,这个enumerateObjectsUsingBlock,这个方法做什么事情,这个方法的内部,就是把这个数组里面的每1个元素遍历出来,

问题来了,它把这个数组的每1个元素遍历出来之后,怎么去处理这个元素呢,它怎么处理,它是不是打印,不是,它是不是存到数据库,不是,所以,这个数据怎么处理,需要我自己写一段代码,要让我来处理,我自己写1个block代码块,写1个处理这个数据的代码块,传给它,这样它每次遍历出来以后呢,它就调用我这个代码块,处理它就可以了

这个方法做的事情,将这个arr数组当中的每1个元素,遍历出来,当它将每1个元素遍历出来以后,如何处理遍历出来的元素呢,它知不知道怎么处理啊,不知道,所以要求我们传递1段处理元素的代码过去,它每遍历出来1个元素,它就把这个元素交给我的代码,让我的代码来处理

好,例如:

[arr enumerateObjectsUsingBlock:^(id _Nonnull obj,NSUInteger idx,BOOL * _Nonnull stop){

//code

}];

这是不是有3个参数啊,不要管后面的参数,我们只管第一个参数,obj,它每遍历出来一个元素,它就把它遍历出来的元素,传给我这个参数obj,让我来处理,

[arr enumerateObjectsUsingBlock:^(id _Nonnull obj,NSUInteger idx,BOOL * _Nonnull stop){

NSLog(@“%@.length = %lu”,obj,[obj length]);

}];

我干嘛呢,我打印吧

输出:jack.length = 4

rose.length = 4

Jim.length = 3

所以,obj就是每1个元素

那idx参数呢

NSUInteger idx参数:这个元素的下标

idx就是index嘛

NSLog(@“Idx = %lu”,idx);

输出:idx = 0

idx = 1

idx = 2

所以,它每次遍历出来1个元素以后,它不仅会把这个元素传给我,还会把这个元素的下标传给我,

所以说,我想得到下标的话,得到当前这个元素的下标的话,我就可以用这个idx,就可以得到下标了

第三个参数BOOL * _Nonnull stop什么意思呢

你先不要管这个Nonnull,就看这个

BOOL *stop

这个是一个BOOL类型的指针吧

那我是不是可以这么做

*stop = NO;

是不是可以给它改值啊

这个改的是什么呢,stop这个指针所指向的BOOL变量的值,改成NO

那我改成NO有什么效果呢,

如果你想停止循环,那么,你就把这个stop指针指向的变量的值,改成YES,就可以了

如果想停止遍历,就将stop指针指向的BOOL变量的值,改为YES,就可以了

例如:

if(idx == 1){

*stop = YES;

}

输出:jack.length = 4

idx = 0

rose.length = 4

idx = 1

你看,只遍历几对出来啊,两对

当它遍历第二个的时候,是不是idx == 1 啊

idx == 1时,我就把*stop = YES,那这个它就停掉了

以上,就是使用block来遍历NSArray数组当中的元素

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

清风清晨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值