OC中数组类NSArray的详解,数组的遍历(二)

数组类的便利

1.for循环(大家都会的...)

2.NSEmunerator

3.for in

首先重点说下 第二种NSEmunerator枚举器,系统声明是

 1 @interface NSEnumerator : NSObject <NSFastEnumeration>
 2 
 3 - (id)nextObject;
 4 
 5 @end
 6 
 7 @interface NSEnumerator (NSExtendedEnumerator)
 8 
 9 @property (readonly, copy) NSArray *allObjects;
10 
11 @end
NSEmunerator系统声明

依附于集合类(NSA􏰄􏰄a􏰅rray,NSSe􏰁t,NSDic􏰁iona􏰄􏰅ry),没有用来创建实例的接口(虽然有父类的init,但不建议使用)。

通过- (id)nextObject方法便利数据,属性@property (readonly, copy) NSArray *allObjects可以获取剩余的所有元素。

用法举例

 1 NSMutableArray *arr = [NSMutableArray arrayWithObjects:[@"test1" mutableCopy],[@"test2" mutableCopy], nil];
 2         
 3         NSEnumerator *emumer = [arr objectEnumerator];
 4         
 5         NSMutableString *temp = nil;
 6         while (temp = [emumer nextObject]) {
 7             [temp appendFormat:@"-xin"];
 8         }
 9         temp = [emumer nextObject];
10         NSLog(@"%@",temp);
11         NSLog(@"%@",arr);
枚举器使用代码

在上面代码中创建了一个可变数组,存储了两个可变字符串,然后通过while循环遍历了数组,并把每个元素后面拼上了-xin字符串,循环后面有这么两句代码

temp = [emumer nextObject];    NSLog(@"%@",temp); 打印结果为null 说明枚举器便利到数组最后继续调用nextObject虽然不会使程序崩溃,但得到的结果都是nil的。

枚举器枚举枚举过程中不能改变数组元素的个数,也不能改变数组元素的指向(其实这个是线程安全的,别的线程也不能改变它,保证了便利过程中数据的有效性)。

 1         NSMutableArray *arr = [NSMutableArray arrayWithObjects:[@"test1" mutableCopy],[@"test2" mutableCopy], nil];
 2         NSEnumerator *emumer = [arr objectEnumerator];
 3         
 4         NSMutableString *temp = nil;
 5         while ((temp = [emumer nextObject]) != nil) {
 6             [temp appendFormat:@"-xin"];
 7             [arr removeObjectAtIndex:0];//改变数组元素个数
 8             arr[0] = [@"newItem" mutableCopy]; //改变数组元素指向
 9         }
10         NSLog(@"%@",arr);
导致程序崩溃的实例代码

由以上实例代码看出无论是试图改变数组元素个数还是改变数组元素的指向,都会导致程序崩溃。

在开始的枚举器使用代码中我们改变了数组元素的对象内容,程序并没有崩溃,因为只是改变了数组元素指向地址的内容,数组本身并没有改变。

1         NSMutableArray *arr = [NSMutableArray arrayWithObjects:[@"test1" mutableCopy],[@"test2" mutableCopy], nil];
2         NSEnumerator *emumer = [arr objectEnumerator];
3         NSLog(@"%@",[emumer nextObject]);
4         NSLog(@"%@",[emumer allObjects]);
5         NSLog(@"%@",[emumer nextObject]);
allObjects属性的举例说明

以上的打印结果是,说明allObjects不但会获取剩余所有的元素,还会将枚举器指向数组最后,也就是nil。

2015-12-26 10:47:02.612 test[810:35136] test1

2015-12-26 10:47:02.612 test[810:35136] (

    test2

)

2015-12-26 10:47:02.612 test[810:35136] (null)

*有个反向枚举的概念NSEnumerator *reverse = [array reverseObjectEnumerator];  就是从数组末尾向数组开始枚举,有兴趣的童鞋可以试下。

 

fo􏰄r...in...快速枚举

 快速枚举其实是枚举器的便利写法,有枚举遍历的一切特性。

1         NSMutableArray *arr = [NSMutableArray arrayWithObjects:[@"test1" mutableCopy],[@"test2" mutableCopy], nil];
2         
3         for (NSMutableString *item in arr) {
4             [item appendFormat:@"-xin"];
5         }
6         NSLog(@"%@",arr);
快速枚举

下面是错误用法

1         NSMutableArray *arr = [NSMutableArray arrayWithObjects:[@"test1" mutableCopy],[@"test2" mutableCopy], nil];
2         
3         for (NSMutableString *item in arr) {
4             [item appendFormat:@"-xin"];
5             item = [@"xintest" mutableCopy];        //会导致程序编译不过
6             [arr removeObjectAtIndex:0];            //运行会崩溃
7         }
8         NSLog(@"%@",arr);
快速遍历的错误示例

需要特别注意的其实就一点NSMutableString *item 不要把它看成一个临时变量(只是一个临时变量的话改变指向不会使编译不过),它其实就是数组中的一个元素和for

循环中的arr[i]等价。

 

最后说下字典和集合的枚举遍历的注意点

1.字典和集合是无序的,所以没有反序输出的概念

2.字典的枚举器获取有两个方法

[dictionary keyEnumerator]获取键值的枚举器

[dictionary objectEnumerator]获取value的枚举器。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted @ 2015-12-26 11:36  小红烧  阅读(317)  评论(0编辑  收藏  举报