【iOS】 Foundation 数组

NSArray数组代表元素有序、可重复的一个集合,集合中每个元素都有其对应的顺序索引,可以通过索引来访问指定位置的集合元素。

NSArray的功能与用法

NSArray分别提供了类方法和实例方法来创建NSArray,两种创建方式需要传入的参数基本相似,只是类方法以array开头,而实例方法则以init开头

下面程序示范了NSArray集合的常规用法:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        NSArray* array = [NSArray arrayWithObjects:
                          @"疯狂iOS讲义",
                          @"疯狂Android讲义",
                          @"疯狂Ajax讲义",
                          @"疯狂XML讲义",
                          @"疯狂Swift讲义",
                          nil];
        NSLog(@"第一个元素为:%@" , [array objectAtIndex:0]);
        NSLog(@"索引为1的元素为:%@" , [array objectAtIndex:1]);
        NSLog(@"最后一个元素为:%@" , [array lastObject]);
        //获取从索引为2的元素开始,以及后面3个元素组成的新集合
        NSArray* arr1 = [array objectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(2, 3)]];
        NSLog(@"%@" , arr1);
        //获取元素在集合指定位置范围中的位置
        NSLog(@"在2~5范围疯狂Android讲义的位置为:%ld" , [array indexOfObject:@"疯狂Android讲义"]);
        //获取元素在集合中的位置
        NSLog(@"疯狂Android讲义的位置为%ld" , [array indexOfObject:@"疯狂Android讲义" inRange:NSMakeRange(2, 3)]);
        //向数组的最后追加一个元素
        //原NSArray本身并没有改变,只是将新返回的NSArray赋给array
        array = [array arrayByAddingObject:@"孙悟空"];
        //向array数组的最后追加另一个数组的所有元素
        //原NSArray本身并没有改变,只是将新返回的NSArray赋给array
        array = [array arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:@"宝玉", @"黛玉", nil]];
        for (int i = 0; i < array.count; i++) {
    
    
            NSLog(@"%@" , [array objectAtIndex:i]);
            //也可以写为
            //NSLog(@"%@" , array[i]);
        }
        //获取array数组中索引为5-8的所有元素
        NSArray* arr2 = [array subarrayWithRange:NSMakeRange(5, 3)];
//        NSLog(@"%@" , [array objectAtIndex:0]);
        //将NSArray集合写入文件
        [arr2 writeToFile:@"/Users/haoqianbiao/Desktop/test1/practice/数组/未命名.txt" atomically:YES];
    }
    return 0;
}

程序遍历NSArray集合时,既可以通过调用NSArray的objectAtIndex:index方法来访问指定索引处的元素,也可以直接使用类似普通数组的下标表示法来访问元素。

[array objectAtIndex:i];
array[i];

但是后一种方法只能在iOS 5.0 以上的系统中使用。当程序调用array[i]语法来访问元素时,实际上就是调用NSArray的objectAtIndexedSubscript:方法进行访问。

运行以上结果,将看到如下运行结果:
在这里插入图片描述

不管上面的哪一种方法,都不会对原有NSArray产生任何修改(因为NSArray集合本身是不能修改的),程序只是返回一个新的NSArray对象。

从上面程序输出的结果可以看出,当程序直接输出NSArray集合,虽然会输出集合元素,但对于中文字符,则转为形如“\U75af”格式的Unicode表示形式。

NSArray判断指定元素位于NSArray集合中的索引的标准只有一条:只有某个集合元素与被查找元素通过isEqual: 方法比较返回YES时,才可以认为该NSArray集合包含该元素,并不需要两个元素是同一个元素。

下面代码证实NSArray的比较机制:


//FKUser.h
#import <Foundation/Foundation.h>

@interface FKUser : NSObject
@property (nonatomic , copy) NSString* name;
@property (nonatomic , copy) NSString* pass;
- (id) initWithName: (NSString*) aName pass:(NSString*) pass;
- (void) say:(NSString*) content;
@end
//FKUser.m

#import "FKUser.h"

@implementation FKUser
- (id) initWithName:(NSString *) aName pass:(NSString *) apass {
    
    
    if (self = [super init]) {
    
    
        self.name = aName;
        self.pass = apass;
    }
    return self;
}

- (BOOL) isEqual:(id)other
{
    
    
    if (self == other) {
    
    
        return YES;
    }
    if ([other class] == FKUser.class) {
    
    
        FKUser* target = (FKUser*)other;
        return [self.name isEqualToString:target.name];
    }
    return NO;
}

- (id) description {
    
    
    return self.name;
}
- (void) say:(NSString *)content {
    
    
    NSLog(@"%@说:%@" , self.name , content);
}
@end
//main.m

#import <Foundation/Foundation.h>
#import "FKUser.h"
int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        NSArray* array = @[
                           [[FKUser alloc] initWithName:@"sun" pass:@"123"],
                           [[FKUser alloc] initWithName:@"bai" pass:@"345"],
                           [[FKUser alloc] initWithName:@"zhu" pass:@"654"],
                           [[FKUser alloc] initWithName:@"tang" pass:@"178"],
                           [[FKUser alloc] initWithName:@"niu" pass:@"155"]
                           ];
        //查找指定新的FKUser对象在集合中的索引
        FKUser* newUser = [[FKUser alloc] initWithName:@"zhu" pass:@"654"];
        NSUInteger pos = [array indexOfObject:newUser];
        NSLog(@"newUser的位置为:%ld" , pos);
    }
    return 0;
}

对集合元素整体调用方法

NSArray允许对集合中所有的元素或部分元素整体调用方法。

示例:

#import <Foundation/Foundation.h>
#import "FKUser.h"
int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        NSArray* array = @[
        [[FKUser alloc] initWithName:@"sun" pass:@"123"],
        [[FKUser alloc] initWithName:@"bai" pass:@"345"],
        [[FKUser alloc] initWithName:@"zhu" pass:@"654"],
        [[FKUser alloc] initWithName:@"tang" pass:@"178"],
        [[FKUser alloc] initWithName:@"niu" pass:@"155"]
        ];
        //对集合元素整体调用方法
        [array makeObjectsPerformSelector:@selector(say:) withObject:@"下午好,NSArray真强大!"];
        NSString* content = @"疯狂iOS讲义";
        //迭代集合内指定范围内的元素,并使用该元素来执行代码
        [array enumerateObjectsAtIndexes:[NSIndexSet indexSetWithIndexesInRange: NSMakeRange(2, 2)] options:NSEnumerationReverse usingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    
    
            NSLog(@"正在处理第%ld个元素:%@" , idx , obj);
            [obj say:content];
        }];
    }
    return 0;
}

效果:
在这里插入图片描述

对NSArray进行排序

NSArray提供了大量的方法对集合元素进行排序,这些排序都以sorted开头。

示例:

#import <Foundation/Foundation.h>

NSComparisonResult intSort (id num1, id num2, void *context) {
    
    
    int v1 = [num1 intValue];
    int v2 = [num2 intValue];
    if (v1 < v2) {
    
    
        return NSOrderedAscending;
    } else if (v1 > v2) {
    
    
        return NSOrderedDescending;
    } else {
    
    
        return NSOrderedSame;
    }
}

int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        //初始化一个元素为NSString的NSArray对象
        NSArray* array1 = @[@"Objective-C" , @"C" , @"C++" , @"Ruby" , @"Perl" , @"Swift"];
        //使用集合元素的compare:方法进行排序
        array1 = [array1 sortedArrayUsingSelector:@selector(compare:)];
        NSLog(@"%@" , array1);
        //初始化一个元素为NSNumber的NSArray对象
        NSArray* array2 = @[[NSNumber numberWithInt:20] ,
                            [NSNumber numberWithInt:12] ,
                            [NSNumber numberWithInt:-8] ,
                            [NSNumber numberWithInt:50] ,
                            [NSNumber numberWithInt:19]  ];
        array2 = [array2 sortedArrayUsingFunction:intSort context:nil];
        NSLog(@"%@" , array2);
        //使用代码块对集合元素进行排序
        NSArray* array3 = [array2 sortedArrayUsingComparator: ^(id obj1 , id obj2)
                           {
    
    
                               //该代码块就是根据元素的intValuei进行比较
                               if ([obj1 intValue] > [obj2 intValue]) {
    
    
                                   return NSOrderedDescending;
                               }
                               if ([obj1 intValue] < [obj2 intValue])
                               {
    
    
                                   return NSOrderedAscending;
                               }
                               return NSOrderedSame;
                           }];
        NSLog(@"%@" , array3);
    }
    return 0;
}

效果:
在这里插入图片描述

使用枚举器遍历NSArray元素

对于NSArray对象,除了可根据集合元素的索引来遍历集合元素之外,还可以调用NSArray对象的以下两个方法来返回枚举器。
1.objectEnumerator:返回NSArray集合的枚举器。
reverseObjectEnumerator:返回NSArray集合的逆序枚举器。

上面两个方法都返回一个NSEnumerator枚举器,该枚举器只包含以下两个方法。
1.allObjects:获取被枚举集合中的所有元素
2.nextObject:获取被枚举集合中的下一个元素。

一般来说,借助nextObject方法即可对集合元素进行枚举:程序可以采用循环不断获得nextObject方法的返回值,直到该方法的返回值为nil结束循环。

示例:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        //读写前面写入磁盘的文件,用文件内容来初始化NSArray集合
        NSArray* array = [NSArray arrayWithContentsOfFile:@"/Users/haoqianbiao/Desktop/test1/practice/数组/未命名.txt"];
        //获取NSArray的顺序枚举器
        NSEnumerator* en = [array objectEnumerator];
        id object;
        while (object = [en nextObject]) {
    
    
            NSLog(@"%@" , object);
        }
        NSLog(@"------下面顺序遍历------");
        //获取NSArray的逆序枚举器
        en = [array reverseObjectEnumerator];
        while (object = [en nextObject]) {
    
    
            NSLog(@"%@" , object);
        }
    }
    return 0;
}

效果:
在这里插入图片描述

快速枚举(for-in)

语法格式:

for(type variableName in collection)
{
    
    
    //variableName自动迭代访问每个元素...
}

在上面的语法格式中,type是集合元素的类型,variableName是一个形参名,快速枚举自动将集合元素依次赋给该变量。

示例:

#import <Foundation/Foundation.h>

int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        //读取前面写入磁盘的文件,用文件内容来初始化NSArray集合
        NSArray* array = [NSArray arrayWithContentsOfFile:@"/Users/haoqianbiao/Desktop/test1/practice/数组/未命名.txt"];
        for (id object in array) {
    
    
            NSLog(@"%@" , object);
        }
    }
    return 0;
}

在这里插入图片描述

可变数组

NSArray代表集合元素不可变的集合,一旦NSArray创建成功。程序就不能向集合中添加新的元素,不能删除集合中已有的元素,也不能替换集合中的元素。
注:NSArray只是保存对象的指针,因此NSArray只保证这些变量指针中的地址不能改变,但指针变量所指向的对象是可以改变的。

NSArray有一个子类:NSMutableArray,因此它可以作为NSArray使用,它代表的是一个集合元素可变的集合。

示例:

#import <Foundation/Foundation.h>


NSString* NSCollectionToString(NSArray* array) {
    
    
    NSMutableString* result = [NSMutableString stringWithString:@"["];
    for (id obj in array) {
    
    
        [result appendString:[obj description]];
        [result appendString:@", "];
    }
    NSUInteger len = [result length];
    //去掉字符串最后两个字符
    [result deleteCharactersInRange:NSMakeRange(len - 2, 2)];
    [result appendString:@"]"];
    return result;
}
int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        //读取前面写入磁盘的文件,用文件内容来初始化NSMutableArray
        NSMutableArray* array = [NSMutableArray arrayWithContentsOfFile:@"/Users/haoqianbiao/Desktop/test1/practice/数组/未命名.txt"];
        [array addObject:@"疯狂iOS讲义"];//向集合最后添加一个元素
        NSLog(@"最后一个追加元素后%@" , NSCollectionToString(array));
        //使用NSArray向集合尾部添加多个元素
        [array addObjectsFromArray:[NSArray arrayWithObjects:@"张飞" , @"关羽" , nil]];
        NSLog(@"最后追加两个元素后:%@" , NSCollectionToString(array));
        //向集合的指定位置插入一个元素
        [array insertObject:@"疯狂Ajax讲义" atIndex:2];
        NSLog(@"在索引为2处插入一个元素后:%@" , NSCollectionToString(array));
        //使用NSArray向集合指定位置插入多个元素
        [array insertObjects:[NSArray arrayWithObjects:@"武松" , @"林冲" , nil] atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(3, 2)]];
        NSLog(@"插入多个元素后:%@" , NSCollectionToString(array));
        [array removeLastObject];
        NSLog(@"删除最后一个元素后%@" , NSCollectionToString(array));
        [array removeObjectAtIndex:5];
        NSLog(@"删除索引为5处的元素后:%@" , NSCollectionToString(array));
        [array removeObjectsInRange:NSMakeRange(2, 3)];
        NSLog(@"删除索引为2~4处的元素后:%@" , NSCollectionToString(array));
        //替换索引为2处的元素
        [array replaceObjectAtIndex:2 withObject:@"疯狂iOS讲义"];
        NSLog(@"替换索引2处的元素后:%@" , NSCollectionToString(array));
    }
    return 0;
}

效果:
在这里插入图片描述

NSArray的KVC与KVO

NSArray是一个容纳多个对象的集合,NSArray允许直接对集合中的所有元素进行整体的KVC编码。

示例:

#import <Foundation/Foundation.h>
#import "FKUser.h"
NSString* NSCollectionToString(NSArray* array) {
    
    
    NSMutableString* result = [NSMutableString stringWithString:@"["];
    for (id obj in array) {
    
    
        [result appendString:[obj description]];
        [result appendString:@", "];
    }
    NSUInteger len = [result length];
    //去掉字符串最后两个字符
    [result deleteCharactersInRange:NSMakeRange(len - 2, 2)];
    [result appendString:@"]"];
    return result;
}

int main(int argc, const char * argv[]) {
    
    
    @autoreleasepool {
    
    
        NSArray* array = @[
                           [[FKUser alloc] initWithName:@"Hello1"],
                           [[FKUser alloc] initWithName:@"Hello2"],
                           [[FKUser alloc] initWithName:@"Hello3"]];
        id newArr = [array valueForKey:@"name"]; // 1
        NSLog(@"%@" , NSCollectionToString(newArr));
        //对集合中的所有元素整体进行KVC编程
        //将所有集合元素的name属性改为新名字
        [array setValue:@"新名字" forKey:@"name"];  // 2
        NSLog(@"%@" , NSCollectionToString(array));
    }
    return 0;
}

上面的程序中“1、2”行代码对集合元素整体进行了KVC编程,其中第“1”行代码获取所有集合元素的name属性组成的数组;第“2”行代码将所有的集合元素的name属性都设为新值。

效果:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_50990189/article/details/117826058