【OC梳理】NSArray、NSMutableArray
NSArray
NSArray(数组)是一个存储对象的有序集合,可能是被使用最多的集合类。
下面是常用的方法:
创建:
NSString *s1 = @"zhangsan";
NSString *s2 = @"lisi";
NSString *s3 = @"wangwu";
NSArray *array1 = [[NSArray alloc] initWithObjects:s1,s2,s3, nil];
NSArray *array2 = @[s1,s2,s3];
NSArray *array3 = [NSArray arrayWithArray:array2];
获取元素
NSString *str1 = [array1 objectAtIndex:0];
NSString *str2 = array1[0];
获取数组元素中的个数
NSUInteger count = [array1 count];
判断数组中是否包含某一个对象,判断的是指针对象值,不是对象中的值
BOOL isContains = [array1 containsObject:@"zhangsan"];
获取一个对象在数组中的下标值
NSUInteger index = [array1 indexOfObject:@"zhangsan"];
if(index == NSNotFound){
//没有找到
}
数组中存放的如果是字符串的话,可以使用连接符将其所有的元素进行连接:
- 注意数组中的元素必须都是字符串
NSString *content = [array1 componentsJoinedByString:@","];
在原来的数组后面追加元素,返回一个新的数组对象
NSArray *array4 = [array1 arrayByAddingObject:@"zhaoliu"];
数组的遍历
//遍历
for(int i=0;i<array1.count;i++){
NSString *str = [array1 objectAtIndex:i];
NSLog(@"%@",str);
}
//快速遍历
for(NSString *s in array1){
NSLog(@"%@",s);
}
NSMutableArray
NSMutableArray(可变数组)继承于NSArray,对NSArray进行了增删改的扩充:
创建:
- 与NSArray不同的是,不能使用@[]进行创建
NSString *str1 = @"zhangsan";
NSString *str2 = @"lisi";
NSString *str3 = @"wangwu";
NSMutableArray *mArray1 = [[NSMutableArray alloc] initWithObjects:str1,str2,str3, nil];
NSMutableArray *mArray2 = [[NSMutableArray alloc] initWithCapacity:5];
NSMutableArray *mArray3 = [NSMutableArray arrayWithCapacity:5];
NSMutableArray *mArray4 = [NSMutableArray array];
添加元素
//添加元素的方法
[mArray1 addObject:str1];
//添加数组,把mArray1中的所有元素全部添加到mArray2中
[mArray2 addObjectsFromArray:mArray1];
//二维数组
//将mArray1添加到mArray2数组中,这样mArray2就变成了二维数组了
[mArray2 addObject:mArray1];
插入元素
//在指定的位置上插入特定元素
[mArray2 insertObject:@"def" atIndex:0];
替换元素
//替换元素
[mArray2 replaceObjectAtIndex:0 withObject:@"aaa"];
mArray1[0] = @"123";
互换两个元素的位置
//互换两个元素的位置
[mArray2 exchangeObjectAtIndex:0 withObjectAtIndex:3];
删除
//删除指定位置的元素
[mArray2 removeObjectAtIndex:0];
//删除最后一个元素
[mArray2 removeLastObject];
//删除指定的对象
[mArray2 removeObject:@"lisi"];
//删除所有的对象/清空列表
[mArray2 removeAllObjects];
NSMutableArray与NSArray相互赋值
如果用“=”号将NSMutableArray赋值于NSArray,或者反之,会怎样呢?
如下代码:
// NSMutableArray = NSArray
NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:@"1",@"2", nil];
NSArray *array1 = mutableArray;
[array1 addObject:@"3"];
NSLog(@"%@",array1);
// NSArray = NSMutableArray
NSArray *array = @[@"1",@"2"];
NSMutableArray *array2 = array;
[array2 addObject:@"3"];
NSLog(@"%@",array2);
由于Object对象使用“=”赋值时,是将地址指针直接赋值,所以赋值后的类型不会改变。因此:
[array1 addObject:@"3"];
编译不通过(找不到方法),不过由于NSArray是NSMutableArray的父类,所以可以将其修改为[(NSMutableArray *)array1 addObject:@"3"];
即可
NSMutableArray *array2 = array;
会提示⚠️指针类型不兼容,并且运行时会产生unrecognized selector sent to instance
的错误。需要将其修改为NSMutableArray *array2 = [array mutableCopy];
,或者NSMutableArray *array2 = [NSMutableArray arrayWithArray:array];
进行赋值。
NSArray和NSMutableArray的修饰关键字问题
NSArray一般使用copy关键字进行修饰
一般来说,使用NSArray类型的属性,是不希望被外部修改所影响的。
- 使用strong来修饰NSArray,这时使用一个NSMutableArray对其进行赋值,在外部修改NSMutableArray时,该属性也会跟着改变,可能会导致和预期结果不同的情况(除非你希望它能够在外部被修改,不过这种情况一般要用NSMutableArray类型作为属性)。
- 使用copy修饰NSArray,会对赋值的对象进行copy操作,NSMutableArray进行copy后,会返回一个新的NSArray数组,这时对NSMutableArray的操作就不会影响到我们的属性了。
NSMutableArray一般使用strong关键字进行修饰
上面说了,如果使用copy进行修饰,那么赋值后,拿到的将是NSArray对象,虽然可以编译通过,但在对其进行reoveObject等操作时会Crash(unrecognized selector sent to instance)。
也许可以直接重写它的set方法,使用mutableCopy自行拷贝可变数组?
关于数组的copy,如果是NSArray进行copy(浅copy),那么copy后的指针地址和原来一样,如果是NSMutableArray进行copy(单层深copy),copy后的指针地址和原来不一样,但是它们的元素的指针地址都不变(即没有对元素进行copy操作)。
如果需要将可变数组中的元素也进行copy操作,需要调用NSArray *copyArray = [[NSArray alloc] initWithArray:array copyItems:YES];
方法进行完全复制,需要注意的是,完全复制的对象必须实现NSCopying
和NSMutableCopying
协议