Objective-c学习笔记05——NSArray(NSMutableArray)

Objective-C可以开发apple家族系列产品的软件,这里记录成笔记方便日后复习:

一、数组简介

NSArray:用来存储有序数组,它是不可变的,也不能存储C语言中的基本数据类型(int、float、double、enum、struct),也不能存nil,如果需要使用基本数据类型,需要先转成Objective-c中的对象。如NSNumber。另外,数组的最后一个元素一定是nil,表示结束。

二、创建数组

//1、array
NSArray * arr = [NSArray array];    //因为是类方法,所以无需管理内存
//2、arrayWithArray:
NSArray * arr1 = [NSArray arrayWithArray:arr];
//3、arrayWithObject:
NSArray * arr3 = [NSArray arrayWithObject:@"Apple"];
//4、arrayWithObjects:
NSArray * arr4 = [NSArray arrayWithObjects:@"Apple", @"Android", nil];
//5、arrayWithObjects:count:
NSString * str5[3] = {@"aaa", @"BBB", @"CCC"};
NSArray * arr5 = [NSArray arrayWithObjects:str5 count:2]; //获取数量
//6、init
NSArray * arr6 = [[NSArray alloc] init];
arr6 = @[@"LLL", @"IIII", @"BBBB"];
[arr6 release]; //对象需要进行内存释放
//7、initWithArray:
NSArray * arr7 = [[NSArray alloc] initWithArray:arr6];
[arr7 release];
//8、initWithObjects:
NSArray * arr8 = [[NSArray alloc] initWithObjects:arr6, arr5, nil];
//9、initWithObjects:count:
NSArray * arr9 = [[NSArray alloc] initWithObjects:str5 count:1];
[arr9 release];
//10、arrayWithCapacity 初始化可变数组对象的长度
NSMutableArray *array10 = [NSMutableArray arrayWithCapacity:10];
//11、initWithCapacity
NSMutableArray * array101 = [[NSMutableArray alloc] initWithCapacity:10];

*自面量(@) < @[<#objects, ...#>] >

可以使用下面的方式创建数组,并且无需担心内存

NSArray *arr2 = @[@"Apple", @"DELL", @"Lenovo"];

三、数组删除(NSMutableArray)

//1.removeAllObjects 删除数组中所有的Objects
NSMutableArray *list = [[NSMutableArray alloc] init];
Person *car = [[Person alloc] init];
car.price = 10;
car.color = 1;
Person *car1 = [[Person alloc] init];
car1.price = 120;
car1.color = 12;
[list addObject:car];
[list addObject:car1];
NSLog(@"%@", list);
[list removeAllObjects]; // Crash here
 NSLog(@"%@", list);

//2、removeLastObject 删除最后一个object
[list removeLastObject];
NSLog(@"%@", list);

//3、removeObject: //删除指定Object
[list removeObject:car];
NSLog(@"%@", list);

//4、removeObject:inRange: //在指定范围删除car1
NSRange range = {1, 1};
[list removeObject:car1 inRange:range];
NSLog(@"%@", list);

//5、removeObjectAtIndex:  //删除指定下标的object
[list removeObjectAtIndex:3];

//6、removeObjectsInArray: //删除在数组中出现的Object
NSArray * arr00 = @[car];
[list removeObjectsInArray:arr00];
NSLog(@"%@", list);

//7、removeObjectsInRange: //删除指定范围的Object
[list removeObjectsInRange:range];
NSLog(@"%@", list);
[list release];

四、数组修改(NSMutableArray)

//1. arrayByAddingObject 向数组添加值返回新的数组
NSArray * array = @[@"AAA", @"BBB", @"CCC"];
NSString * str11 = @"bb989";
NSLog(@"%@", [array arrayByAddingObject:str11]);

//2.arrayByAddingObjectsFromArray 组合两个数组

NSLog(@"%@", [array arrayByAddingObjectsFromArray:array]);

//3.componentsJoinedByString 数组切成字符串
NSLog(@"%@", [array componentsJoinedByString:@","]);

//4. addObject 向数组添加对象
NSMutableArray * array4 = [NSMutableArray arrayWithObjects:@"aaa", @"bbbb", nil];
[array4 addObject:@"CCC"];
NSLog(@"%@", array4);

//5. addObjectsFromArray 向数组中添加格式化数组
[array4 addObjectsFromArray:array];
NSLog(@"%@", array4);

//6. insertObject:atIndex 在指定下标添加对象
[array4 insertObject:@"OOO" atIndex:1];
NSLog(@"%@", array4);

//7. replaceObjectAtIndex:withObject 替换指定下标的元素
[array4 replaceObjectAtIndex:1 withObject:@"ppp"];
NSLog(@"%@", array4);

//8.setArray 替换原数组
NSArray * array8 = @[@"A", @"B", @"C"];
[array4 setArray:array8];
NSLog(@"%@", array4);

//9.exchangeObjectAtIndex:withObjectAtIndex 交换指定下标的元素
[array4 exchangeObjectAtIndex:1 withObjectAtIndex:2];
NSLog(@"%@", array4);

五、数组查询

NSString * str = @"CCC";
NSArray * array = @[str];
//1.containsObject   是否包含指定对象
if ([array containsObject:str]) {
    NSLog(@"array 包含 str");
}

//2.count  数组中所含元素个数,不包括 nil
NSArray * array2 = [NSArray arrayWithObjects:@"AAA", @"BBBB", nil];
NSLog(@"count = %zi", array2.count);

//3.getObjects:range:
//4.firstObject 返回两个数组中第一个相同的对象元素
NSMutableArray * array4 = [NSMutableArray arrayWithObjects:@"aaa", @"bbbb", nil];
NSLog(@"%@", [array4 firstObjectCommonWithArray:array4]);

//5.lastObject  返回数组最后一个元素
NSMutableArray * array5 = [NSMutableArray arrayWithObjects:@"aaa", @"bbbb", @"ccc",nil];
NSLog(@"%@", [array5 lastObject]);

//6.objectAtIndex 返回指定索引的元素
NSLog(@"%@", [array5 objectAtIndex:1]);

//7.indexOfObject  返回指定对象的下标
NSLog(@"%li", [array5 indexOfObject:@"bbbb"]);

//8.indexOfObject:inRange 返回范围内指定对象的下标
NSRange range = NSMakeRange(0, 3);
NSLog(@"%li", [array5 indexOfObject:@"ccc" inRange:range]);

//9.makeObjectsPerformSelector  给元素发送消息,让数组中的对象全部执行某一方法
//创建两个对象,并且person类有一个play方法。
Person * p1 = [[Person alloc] init];
Person * p2 = [[Person alloc] init];

NSArray * array3 = [[NSArray alloc] initWithObjects:p1, p2, nil];

[array3 makeObjectsPerformSelector:@selector(play)];
//2013-10-18 16:33:08.366 objective-c——NSArray[11732:303] I am a player
//2013-10-18 16:33:08.367 objective-c——NSArray[11732:303] I am a player

[p1 release];
[p2 release];
[array3 release];
//当然还可以使用下面的方法传递参数
//- (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(id)argument;

//10.firstObjectCommonWithArray  返回两个集合中第一个相同的对象元素
NSLog(@"%@", [array5 firstObjectCommonWithArray:array5]);
//2013-10-18 16:27:03.083 objective-c——NSArray[11672:303] Apple

//11.subarrayWithRange: 截取范围内的数组元素
NSLog(@"%@", [array5 subarrayWithRange:range]);

六、数组排序

//1.reverseObjectEnumerator 数组倒序输出
NSArray *array8 = [NSArray arrayWithObjects:@"one",@"two",@"three", nil];
for (NSString * str  in [array8 reverseObjectEnumerator]) {
    NSLog(@"%@", str);
}

//如果只是对字符串的排序,可以利用sortedArrayUsingSelector:方法就可以了,代码如下
//简单排序
void sortArray1(){
    NSArray *array = [NSArray arrayWithObjects:@"abc",@"456",@"123",@"789",@"ef", nil];
    NSArray *sortedArray = [array sortedArrayUsingSelector:@selector(compare:)];
    NSLog(@"排序后:%@",sortedArray);
}

//block排序
void sortArray3(){
NSArray *array = [NSArray arrayWithObjects:@"1bc",@"4b6",@"123",@"789",@"3ef", nil];
    NSArray *sortedArray = [array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
        //这里的代码可以参照上面compare:默认的排序方法,也可以把自定义的方法写在这里,给对象排序
        NSComparisonResult result = [obj1 compare:obj2];
        return result;
    }];
    NSLog(@"排序后:%@",sortedArray);
}

// 升序排列 --> 升序
[_traceArray sortUsingComparator:^NSComparisonResult(Trace *obj1, Trace *obj2){
    return obj1.status &lt; obj2.status;
}];
// 降序排列 --> 降序
[_traceArray sortUsingComparator:^NSComparisonResult(Trace *obj1, Trace *obj2){
    return obj1.status &lt; obj2.status;
}];

NSMutableArray *arr=[NSMutableArray arrayWithObjects:@"abc",@"zcd",@"bcd",@"9987",nil];
NSMutableArray*(^fu)(NSMutableArray*)=^(NSMutableArray*arr){
    NSMutableArray *ar=(NSMutableArray*)[arr sortedArrayUsingSelector:@selector(compare:)];
    return ar;
};

//2.sortedArrayUsingFunction:context  使用自定义方法排序
//    [array8 sortedArrayUsingSelector:&lt; #(SEL)#>];
//3.sortedArrayUsingDescriptors
//    [array8 sortedArrayUsingSelector:&lt; #(SEL)#>]
//4.sortedArrayUsingSelector
//5.sortUsingDescriptors
//6.sortUsingFunction:context
//7.sortUsingSelector

七、数组比较

//1. isEqualToArray 比较两个数组元素是否相等
if ([array5 isEqualToArray:array5]) {
    NSLog(@"array5 equal array5");
}

八、数组遍历

1、 **for循环遍历**
NSUInteger count = array2.count;
for (int i = 0; i &lt; count; i ++) {
    NSLog(@"%@", [array2 objectAtIndex:i]);
}


2、 **for in 遍历**
for (id obj in array2) {
    NSLog(@"%@", obj);
}


3、 **Block 遍历**
[array2 enumerateObjectsUsingBlock:
 ^(id obj, NSUInteger idx, BOOL *stop) {
    NSLog(@"%zi = %@", idx, obj);
    //可以使用 *stop = YES 停止遍历
 }];


4、 **迭代器遍历**
//创建迭代器(正序)
NSEnumerator *enumerator = [array2 objectEnumerator];
//创建迭代器(倒序)
//NSEnumerator *enumerator = [array2 reverseObjectEnumerator];
//nextObject 取得下个元素
id obj = nil;
while(obj = [enumerator nextObject]){
    NSLog(@"%@", obj);
}
//返回迭代器的所有元素,如果放到遍历后面则输出空。
//[enumerator allObjects];

九、NSArray 文件读写

1、 writeToFile写文件,会保存为XML格式的文件。
NSArray * array = @[@"AAA", @"BBB"];
NSString * path = @"/Users/simman/NSarray.xml";
[array writeToFile:path atomically:YES];

2、 arrayWithContentsOfFile:path 读文件(规定格式(如:xml)转数组)
NSArray * array1 = [NSArray arrayWithContentsOfFile:path];
NSLog(@"%@", array1);

十、数组的内存管理

要说明数组的内存管理,我们可以使用类来做演示。
1、 创建Person类

//创建Person类,并复写dealloc方法,使之能打印出当前释放的对象
- (void)dealloc {
    NSLog(@"%@ is released", self);
    [super dealloc];
}

2、 创建三个Person的对象

Person *p1 = [[Person alloc] init];
Person *p2 = [[Person alloc] init];
Person *p3 = [[Person alloc] init];

3、 把三个对象放进数组 array 里

NSArray * array = [[NSArray alloc] initWithObjects:p1, p2, p3, nil];

4、 打印p1 p2 p3的计数器

NSLog(@"p1_RetainCount = %zi,  p1.retainCount);
NSLog(@"p2_RetainCount = %zi", p2.retainCount);
NSLog(@"p3_RetainCount = %zi", p3.retainCount);

控制台输出:
2013-10-18 16:13:19.012 objective-c——NSArray[11579:303] p1_RetainCount = 2
2013-10-18 16:13:19.014 objective-c——NSArray[11579:303] p2_RetainCount = 2
2013-10-18 16:13:19.016 objective-c——NSArray[11579:303] p3_RetainCount = 2

5、 释放p1 p2 p3对象

[p1 release];
[p2 release];
[p3 release];

6、 释放array数组

[array release];

2013-10-18 16:01:01.111 objective-c——NSArray[11543:303] &lt;person: 0x10010a2b0> is released
2013-10-18 16:01:01.112 objective-c——NSArray[11543:303] &lt;/person:>&lt;person: 0x100109a50> is released
2013-10-18 16:01:01.112 objective-c——NSArray[11543:303] &lt;/person:>&lt;person: 0x100108c00> is released
&lt;/person:>

7、 总结
当把对象放进数组中,该对象将执行retain,计数器将 + 1
当数组 release 的时候,会对所有数组元素做 release 操作。