数组作为存储对象的有序集合,可能是平时用到的最多的集合类。NS数组中存放的是Fundation对象,简单类型比如int,float等可以封装为NSNumber对象来存放到数组中。
Objc中数组分为不可变数组和可变数组,可变数组使用NSMutableArray来处理,不可变数组为NSArray,NSMutableArray是NSArray的子类,也就是说继承了NSArray得所有方法

1.创建一个数组

创建一个NSArray

1
2
3
4
5
6
7
NSArray *array = [NSArray arrayWithObjects:@1, @2, @3, nil];

NSMutableArray *array1 = [[NSMutableArray alloc]initWithCapacity:10];

NSMutableArray *array2 = [NSMutableArray array];

NSMutableArray *array1 = [[NSMutableArray alloc]initWithCapacity:0];

使用initWithCapacity方法可以在初始化数组的时候添加一个预留空间,在数组空间超过这个预留空间时候会进行自动追加。不过是再测试中发现这样做并没有提高应有的效率,传言苹果实际上没有采用这个参数。不过这样有个好处是可以做为一个隐性文档来提高代码可读性。

在创建NSArray数组的时候也可以使用语法糖,相对于调用方法更加简单快捷

1
NSArray *array = @[@"Eve", @"Adam", @"Lilith", @"Lilin", @"Satan", @"Lilim"];

2.NSArray 和NSMutableArray 转换

//NSMutableArray 转换NSArray

1
2
3
4
5
// 创建可变数组
NSMutableArray *mutableArray = [NSMutableArray array];
// 使用copy方法获得一个NSArray。使用三木运算符判断当NSArray为nil时候重新初始化一个新的对象
// x?:y == x?x:y;
NSArray *array = [mutableArray copy]?:[NSArray array];

//NSArray 转换NSMutableArray

1
2
3
4
5
6
//初始化一个NSArray
NSArray *array = @[@7, @2 ,@0 ,@1, @6, @8, @3] ;
// 使用mutableCopy方法获得一个NSMutableArray
NSMutableArray *mutableArray = [array mutableCopy]?:[NSMutableArray array];
//使用类方法arrayWithArray进行转换
NSMutableArray *mutableArray2 = [NSMutableArray arrayWithArray:array];

3.查找对象

1
id object  = [array objectAtIndex:index];

同样可以通过语法糖获取

1
id object = array[index];

NSArray提供firstObject, lastObject,方法获取数组的首尾对象,当数组为空时候返回nil。而使用常规方法获取空数组中的对象则会返回NSRangeException异常

1
2
id lastObject  = [array lastObject];
id firstObject = [array firstObject];

为了方便数组中数据量很大的情况下查找数据,苹果已经预先实现二分查找法来遍历数组,这样查询效率将大大提高

1
2
3
4
5
6
7
8
9
10
NSArray *array = @[@"Eve", @"Adam", @"Lilith", @"Lilin", @"Satan", @"Lilim"];
NSMutableArray *mutableArray = [NSMutableArray array];
NSRange range = NSMakeRange(0, 5);
NSInteger index = [array indexOfObject:@0 inSortedRange:range options:NSBinarySearchingInsertionIndex usingComparator:^NSComparisonResult(id obj1, id obj2) {
if (obj1 < obj2) {
return NSOrderedAscending;
}
return NSOrderedDescending;
}];
id object = mutableArray[index];

4.排序

有很多方法可以对数组进行排序,如果数组中存放的是字符串对象,可以使用sortedArrayUsingSelector:方法进行排序

1
2
NSArray *array = @[@"Eve", @"Adam", @"Lilith", @"Lilin"];
NSArray *newArray = [array sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];

如果数组存放的是数字,可以使用compare:方法进行排序

1
2
NSArray *array = @[@4, @0, @8, @9, @11];
NSArray *newArray = [array sortedArrayUsingSelector:@selector(compare:)];

可是使用reverseObjectEnumerator.allObjects获得一个数组的逆序排列

1
2
NSArray *array = @[@4, @0, @8, @9, @11];
NSArray *newArray = array.reverseObjectEnumerator.allObjects;

5.枚举

从一个数组过滤一些元素,组成另一个数组使我们经常遇到的一个场景,同样Objc提供了很多方法可以实现
1.快速枚举 NSFastEnumeration(for in)
使用快速枚举在数组数据量较大的情况下效率会比传统的for循环提高很多,而且快速枚举代码的可读性也更高

1
2
3
4
5
6
7
NSArray *array = @[@"Eve", @"Adam", @"Lilith", @"Lilin", @"Satan", @"Lilim"];
NSMutableArray *newArray = [NSMutableArray array];
for (NSString *godName in array) {
if ([godName containsString:@"l"]) { [newArray addObject:godName];
}
}
NSLog(@"%@",newArray);

2.使用indexesOfObjectsWithOptions方法
当数据量很大的情况下,使用indexesOfObjectsWithOptions方法的NSEnumerationConcurrent参数可以开启同步执行,但这也只是在数据量很大的情况下,当数据量较少时候因为需要额外的线程管理效率会变得更低一些

1
2
3
4
5
6
7
8
9
10
11
12
NSArray *array = @[@"Eve", @"Adam", @"Lilith", @"Lilin", @"Satan", @"Lilim"];
NSIndexSet *indexSet = [array indexesOfObjectsWithOptions:NSEnumerationConcurrent passingTest:^BOOL(id obj, NSUInteger idx, BOOL *stop) {
if ([obj isKindOfClass:[NSString class]]) {
NSString *godName = obj;
if ([godName containsString:@"l"]) {
return obj;
}
}
return nil;
}];
NSArray *newArray = [array objectsAtIndexes:indexSet];
NSLog(@"%@",newArray);