不可变数组
下面将演示常用的数组操作:初始化、数组对象的方法执行、数组元素的遍历、在原有数组基础上产生新数组、数组排序等
// // main.m // FoundationFramework // // Created by Kenshin Cui on 14-2-16. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import <Foundation/Foundation.h> #import "Person.h" void test1(){ //NSArray长度不可变所以初始化的时候就赋值,并且最后以nil结尾 //此外需要注意NSArray不能存放C语言的基础类型 NSObject *obj=[[NSObject alloc]init]; //NSArray *array1=[[NSArray alloc] initWithObjects:@"abc",obj,@"cde",@"opq", nil]; NSArray *array1=[NSArray arrayWithObjects:@"abc",obj,@"cde",@"opq",@25, nil]; NSLog(@"%zi",array1.count);//数组长度,结果:5 NSLog(@"%i",[array1 containsObject:@"cde"]);//是否包含某个对象,结果:1 NSLog(@"%@",[array1 lastObject]);//最后一个对象,结果:25 NSLog(@"%zi",[array1 indexOfObject:@"abc"]);//对象所在的位置:0 Person *person1=[Person personWithName:@"Kenshin"]; Person *person2=[Person personWithName:@"Kaoru"]; Person *person3=[Person personWithName:@"Rosa"]; NSArray *array2=[[NSArray alloc]initWithObjects:person1,person2,person3, nil]; [array2 makeObjectsPerformSelector:@selector(showMessage:) withObject:@"Hello,world!"];//执行所有元素的showMessage方法,后面的参数最多只能有一个 /*结果: My name is Kenshin,the infomation is "Hello,world!". My name is Kaoru,the infomation is "Hello,world!". My name is Rosa,the infomation is "Hello,world!". */ } //数组的遍历 void test2(){ NSObject *obj=[[NSObject alloc]init]; NSArray *array=[[NSArray alloc] initWithObjects:@"abc",obj,@"cde",@"opq",@25, nil]; //方法1 for(int i=0,len=array.count;i<len;++i){ NSLog(@"method1:index %i is %@",i,[array objectAtIndex:i]); } /*结果: method1:index 0 is abc method1:index 1 is <NSObject: 0x100106de0> method1:index 2 is cde method1:index 3 is opq method1:index 4 is 25 */ //方法2 for(id obj in array){ NSLog(@"method2:index %zi is %@",[array indexOfObject:obj],obj); } /*结果: method2:index 0 is abc method2:index 1 is <NSObject: 0x100602f00> method2:index 2 is cde method2:index 3 is opq method2:index 4 is 25 */ //方法3,利用代码块方法 [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { NSLog(@"method3:index %zi is %@",idx,obj); if(idx==2){//当idx=2时设置*stop为YES停止遍历 *stop=YES; } }]; /*结果: method3:index 0 is abc method3:index 1 is <NSObject: 0x100106de0> method3:index 2 is cde */ //方法4,利用迭代器 //NSEnumerator *enumerator= [array objectEnumerator];//获得一个迭代器 NSEnumerator *enumerator=[array reverseObjectEnumerator];//获取一个反向迭代器 //NSLog(@"all:%@",[enumerator allObjects]);//获取所有迭代对象,注意调用完此方法迭代器就遍历完了,下面的nextObject就没有值了 id obj2=nil; while (obj2=[enumerator nextObject]) { NSLog(@"method4:%@",obj2); } /*结果: method4:25 method4:opq method4:cde method4:<NSObject: 0x100106de0> method4:abc */ } //数组派生出新的数组 void test3(){ NSArray *array=[NSArray arrayWithObjects:@"1",@"2",@"3", nil]; NSArray *array2=[array arrayByAddingObject:@"4"];//注意此时array并没有变 NSLog(@"%@",array2); /*结果: ( 1, 2, 3, 4 ) */ NSLog(@"%@",[array2 arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:@"5",@"6", nil]]);//追加形成新的数组 /*结果: ( 1, 2, 3, 4, 5, 6 ) */ NSLog(@"%@",[array2 subarrayWithRange:NSMakeRange(1, 3)]);//根据一定范围取得生成一个新的数组 /*结果: ( 2, 3, 4 ) */ NSLog(@"%@",[array componentsJoinedByString:@","]);//数组连接,形成一个字符串 //结果:1,2,3 //读写文件 NSString *path=@"/Users/KenshinCui/Desktop/array.xml"; [array writeToFile:path atomically:YES]; NSArray *array3=[NSArray arrayWithContentsOfFile:path]; NSLog(@"%@",array3); /*结果: ( 1, 2, 3 ) */ } //数组排序 void test4(){ //方法1,使用自带的比较器 NSArray *array=[NSArray arrayWithObjects:@"3",@"1",@"2", nil]; NSArray *array2= [array sortedArrayUsingSelector:@selector(compare:)]; NSLog(@"%@",array2); /*结果: ( 1, 2, 3 ) */ //方法2,自己定义比较器 Person *person1=[Person personWithName:@"Kenshin"]; Person *person2=[Person personWithName:@"Kaoru"]; Person *person3=[Person personWithName:@"Rosa"]; NSArray *array3=[NSArray arrayWithObjects:person1,person2,person3, nil]; NSArray *array4=[array3 sortedArrayUsingSelector:@selector(comparePerson:)]; NSLog(@"%@",array4); /*结果: ( "name=Kaoru", "name=Kenshin", "name=Rosa" ) */ //方法3使用代码块 NSArray *array5=[array3 sortedArrayUsingComparator:^NSComparisonResult(Person *obj1, Person *obj2) { return [obj2.name compare:obj1.name];//降序 }]; NSLog(@"%@",array5); /*结果: ( "name=Rosa", "name=Kenshin", "name=Kaoru" ) */ //方法4 通过描述器定义排序规则 Person *person4=[Person personWithName:@"Jack"]; Person *person5=[Person personWithName:@"Jerry"]; Person *person6=[Person personWithName:@"Tom"]; Person *person7=[Person personWithName:@"Terry"]; NSArray *array6=[NSArray arrayWithObjects:person4,person5,person6,person7, nil]; //定义一个排序描述 NSSortDescriptor *personName=[NSSortDescriptor sortDescriptorWithKey:@"name" ascending:YES]; NSSortDescriptor *accountBalance=[NSSortDescriptor sortDescriptorWithKey:@"account.balance" ascending:YES]; NSArray *des=[NSArray arrayWithObjects:personName,accountBalance, nil];//先按照person的name排序再按照account的balance排序 NSArray *array7=[array6 sortedArrayUsingDescriptors:des]; NSLog(@"%@",array7); /*结果: ( "name=Jack", "name=Jerry", "name=Terry", "name=Tom" ) */ } int main(int argc, const char * argv[]) { test1(); test2(); test3(); test4(); return 0; }
需要注意几点:
- NSArray中只能存放对象,不能存放基本数据类型,通常我们可以通过在基本数据类型前加@进行转换;
- 数组中的元素后面必须加nil以表示数据结束;
- makeObjectsPerformSelector执行数组中对象的方法,其参数最多只能有一个;
- 上面数组操作中无论是数组的追加、删除、截取都没有改变原来的数组,只是产生了新的数组而已;
- 对象的比较除了使用系统自带的方法,我们可以通过自定义比较器的方法来实现;
可变数组
下面看一下可变数组的内容:
// // main.m // FoundationFramework // // Created by Kenshin Cui on 14-2-16. // Copyright (c) 2014年 Kenshin Cui. All rights reserved. // #import <Foundation/Foundation.h> #import "Person.h" void test1(){ Person *person1=[Person personWithName:@"Kenshin"]; Person *person2=[Person personWithName:@"Kaoru"]; Person *person3=[Person personWithName:@"Rosa"]; NSMutableArray *array1=[NSMutableArray arrayWithObjects:person1,person2,person3, nil]; NSLog(@"%@",array1); /*结果: ( "name=Kenshin", "name=Kaoru", "name=Rosa" ) */ Person *person4=[Person personWithName:@"Jack"];//此时person4的retainCount为1 [array1 addObject:person4];//添加一个元素,此时person4的retainCount为2 NSLog(@"%@",array1); /*结果: ( "name=Kenshin", "name=Kaoru", "name=Rosa", "name=Jack" ) */ [array1 removeObject:person3];//删除一个元素 NSLog(@"%@",array1); /*结果: ( "name=Kenshin", "name=Kaoru", "name=Jack" ) */ [array1 removeLastObject];//删除最后一个元素,//此时person4的retainCount为1 NSLog(@"%@",array1); /*结果: ( "name=Kenshin", "name=Kaoru" ) */ [array1 removeAllObjects];//删除所以元素 //注意当往数组中添加一个元素时会retain因此计数器+1,当从数组中移除一个元素时会release因此计数器-1 //当NSMutalbeArray对象release的时候会依次调用每一个对象的release } void test2(){ NSMutableArray *array1=[NSMutableArray arrayWithObjects:@"1",@"3",@"2", nil]; NSLog(@"%@",array1); /*结果: ( 1, 3, 2 ) */ NSArray *array2= [array1 sortedArrayUsingSelector:@selector(compare:)];//注意这个方法没有修改array1 NSLog(@"%@",array1); /*结果: ( 1, 3, 2 ) */ NSLog(@"%@",array2); /*结果: ( 1, 2, 3 ) */ [array1 sortUsingSelector:@selector(compare:)];//这个方法会修改array1 NSLog(@"%@",array1); /*结果: ( 1, 2, 3 ) */ } int main(int argc, const char * argv[]) { test1(); test2(); return 0; }
- 可变数组中的元素后面必须加nil以表示数据结束;
- 往一个可变数组中添加一个对象,此时这个对象的引用计数器会加1,当这个对象从可变数组中移除其引用计数器减1。同时当整个数组销毁之后会依次调用每个对象的releaes方法。
- 在不可变数组中无论对数组怎么排序,原来的数组顺序都不会改变,但是在可变数组中如果使用sortUsingSelector:排序原来的数组顺序就发生了变化。