Objective-C之NSArray学习笔记(IOS 9.1)

时间:2022-06-09
本文章向大家介绍Objective-C之NSArray学习笔记(IOS 9.1),主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

NSArray类简介

  1. 有序且只可以存储Objective-C对象的数组
  1. 初始化后,内容不可变,长度也不可变,不能进行增、删、改操作
  1. 不能存放nil (nil是标志数组的结束)
  1. 在MRC模式下,会发送retain消息于每个加入数组中的元素都进行保持,数组被释放的时候会发送release消息

属性表(@property)

@property

描述

@property(readonly) NSUInteger count

数组元素的个数

@property(nonatomic, readonly) ObjectType firstObject

返回数组中的第一个元素

@property(nonatomic, readonly) ObjectType lastObject

返回数组中的最后一个元素

@property(readonly, copy) NSData *sortedArrayHint

用于排序

@property(readonly, copy) NSString *description

返回数组的内容“(内容在这)”


常用方法

常用类方法

数组对象的生成

+ (instancetype)array // 生成并返回一个空的数组对象
+ (instancetype)arrayWithObject:(ObjectType)anObject // 返回一个只有anObject的数组对象 

常用实例方法

数组对象的初始化

- (instancetype)initWithObjects:(ObjectType)firstObj, ... //返回以firstObj等元素生成的数组,以nil结束

便利构造器:arrayWithObjects:


- (instancetype)initWithObjects:(const ObjectType _Nonnull[])objects count:(NSUInteger)count    //返回包含前count个objects的数组

便利构造器:arrayWithObjects:count:


- (instancetype)initWithArray:(NSArray<ObjectType> *)anArray //使用anArray来生成一个新的数组

便利构造器:arrayWithArray:


- (instancetype)initWithArray:(NSArray<ObjectType> *)array copyItems:(BOOL)flag //falg为YES的时候,底层会使用copyWithZone:方法为每个array元素生成一个副本,并把新生成的副本数组返回

数组元素的访问

- (NSUInteger) count //返回元素数量
- (NSUInteger)indexOfObject:(ObjectType)anObject //返回数组中元素为anObject的最小的下标(利用isEqual:方法进行比较)
- (BOOL)containsObject:(ObjectType)anObject //判断数组中是否有anObject元素,如果没有就返回NSNotFound(宏定义,就是没有找到的意思)
- (ObjectType)objectAtIndex:(NSUInteger)index //返回下标对应的元素(index大于数组的count时就发生NSRangeException异常)
@property(nonatomic, readonly) ObjectType lastObject //返回数组中的最后一个元素,如果没有接收者(就是没有取值操作)就返回nil
- (void)getObjects:(ObjectType _Nonnull [])aBuffer range:(NSRange)aRange //根据aRange指定的范围复制数组元素到C语言的aBuffer缓冲区中(aBuffer可以通过malloc进行创建)
- (NSArray<ObjectType> *)subarrayWithRange:(NSRange)range //返回根据aRange指定的范围从原数组中生成一个新的数组

数组元素的比较

- (BOOL)isEqualToArray:(NSArray<ObjectType> *)otherArray //判断两个数组的元素是否一致(相同下标所对应的元素要相等)
- (ObjectType)firstObjectCommonWithArray:(NSArray<ObjectType> *)otherArray //返回消息接收者与otherArray第一个相同的元素

添加新元素到数组(间接添加,返回一个新数组)

- (NSArray<ObjectType> *)arrayByAddingObject(ObjectType)anObject //返回一个由消息接收者和anObject共同组成的新数组(anObject加到新数组的末尾)
- (NSArray<ObjectType> *)arrayByAddingObjectsFromArray:(NSArray<ObjectType> *)otherArray //返回一个由消息接收者和otherArray共同组成的新数组(otherArray加到新数组的末尾)

数组元素的排序

- (NSArray<ObjectType> *)sortedArrayUsingSelector:
(SEL)comparator //使用指定方法comparator(可以自定义,也可以使用对象本身拥有的方法;要求必须要有一个参数,且其返回值必须为以下三种情况中的一种:
 1. NSOrderedAscending  消息接收者元素 < 形参元素
 2. NSOrderedSame       消息接收者元素 == 形参元素
 3. NSOrderedDescending 消息接收者元素 > 形参元素
),返回排好序的新数组
- (NSArray<ObjectType> *)sortedArrayUsingFunction:
(NSInteger (*)(ObjectType, ObjectType, void *))comparator
context:(void *)context //使用指定的comparator方法(要求必须要有三个形式参数,前两个是数组中的元素,第三个元素是自定义形参;返回值是NSComparisonResult类型(NSInteger也行),该类型的值就是前面方法中的NSOrderedSame等三者),返回一个排好序的新数组

向数组中的元素发送消息

- (void)makeObjectsPerformSelector:(SEL)aSelector //为数组中的每一个元素发送一条消息(aSelector指定的方法),从数组的第一个元素依次发送到最后一个元素为止
//注意:
//  i: aSelector指定的方法不能有参数
// ii: 指定的方法发生波及作用(就是改变数组之类的操作)
//iii: 如果没有指定的方法会抛出NSInvalidArgumentException异常
- (void)makeObjectsPerformSelector:(SEL)aSelector
withObject:(id)anObject //为数组中的每一个元素发送一条消息(aSelector指定的方法),从数组的第一个元素依次发送到最后一个元素为止
//注意:
//  i: aSelector指定的方法只能有一个参数anObject
// ii: 指定的方法发生波及作用(就是改变数组之类的操作)
//iii: 如果没有指定的方法会抛出NSInvalidArgumentException异常

数组的文件输入与输出操作

- (NSString *)description //以ASCII编码的属性列表格式输出数组的元素

- (NSArray<ObjectType> *)initWithContentsOfFile:(NSString *)aPath //根据属性列表格式保存的文件来初始化数组,aPath指文件路径

便利构造器:arrayWithContentsOfFile:


- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)flag //把代表这个数组内容的属性列表输出到指定的文件中,path指点生成的文件的路径(flag是控制写入的,如果为YES则表示完全写入)

参考方法(NSString):writeToFile: atomically: encoding: error:


- (NSString *)componentsJoinedByString:(NSString *)separator //把数组元素(以“,”分隔的元素)自第一个元素至最后一个元素用separator连接起来形成字符串(假设separatoro "-"即:firstObject-SecondObject...-LastObject)
- (NSArray<NSString *> *)pathsMatchingExtensions:(NSArray<NSString *> *)filterTypes //筛选具有特定扩展名的字符串,如:“.jpg”

数组的遍历

- (NSEnumerator<ObjectType> *)objectEnumerator //返回一个枚举器,用于遍历数组

数组,小试牛刀

//Xcode 7.2
 #import <Foundation/Foundation.h>

@interface msgTest : NSObject
- (void)test;
- (void)oneTest:(NSNumber *)num;
@end

@implementation msgTest

- (void)test{

    NSLog(@"7 --> I am a msgTest class!");
}

- (void)oneTest:(NSNumber *)num{
    
    NSLog(@"7 --> num = %d", [num intValue]);
}

@end

//官方Demo
NSInteger 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 {
        
        //1.数组对象的生成
        //1.1 //返回空的数组对象
        NSArray *arry1_1 = [NSArray array];
        NSLog(@"arry1_1 --> %@",arry1_1);    //打印对象的内容,返回一个字符串“( 内容在这 )”
        //1.2 返回一个只有 @"你好!数组!" 元素的数组
        NSArray *arry1_2 = [NSArray arrayWithObject:@"你好!数组!"];
        NSLog(@"arry1_2 --> %@",[arry1_2 description]);
        
        //2.数组对象的初始化
        //2.1 返回一个以@[@"-1-",@"-2-",@"-3-"] - @[@1,@2,@3]为基础逐一创建的,“-1-” - 1,“-2-” - 2,“-3-” - 3共三条词条的词典对象
        NSArray *arry2_1 = [[NSArray alloc] initWithObjects:@3,@[@"oneObject",@"twoObject"], nil];
        NSLog(@"arry2_1 --> %@",arry2_1);
        //2.2 IOS 9.1可以用,但IOS 9.2 不可以了
//        NSArray *arry2_2 = [[NSArray alloc] initWithObjects:(const id  _Nonnull __unsafe_unretained *) count:(NSUInteger)]
        
        //2.3 根据arry2_1数组生成arry2_3
        NSArray *arry2_3 = [[NSArray alloc] initWithArray:arry2_1];
        NSLog(@"arry2_3 --> %@",arry2_3);
        //2.4 copeItem值为YES的时候会以arry为蓝本生成一个副本返回组arry2_4
        NSArray *arry = @[@"1", @"2", @"3", @"4"];
        NSArray *arry2_4 = [[NSArray alloc] initWithArray:arry copyItems:YES];
        NSLog(@"arry2_4 --> %@",arry2_4);
        
        //3.数组对象的访问--------------=====
        NSArray *arry3 = @[@1,@2,@3,@"4",@[@"1",@"2",@YES],@2.0f];//快速生成数组,只能用在NSArray处,因为生成的数组是不可变的
        //3.1 元素的数量
        NSLog(@"arry3 --> %@,词条数:%lu",arry3, [arry3 count]);
        //3.2 通过 object 获取相应的 index
        NSLog(@"arry3 --> %lu", [arry3 indexOfObject:@2]);
        NSLog(@"arry3 --> %lu", [arry3 indexOfObject:@YES]);
        //3.3 根据 index 获取相应的 object
        NSString *str = [arry3 objectAtIndex:3];
        NSArray *arryTemp = [arry3 objectAtIndex:4];
        NSLog(@"str = %@, arryTemp = %@", str, arryTemp);

        //3.4 获取数组中的第一个元素和最后一个元素                [NSNumber intValue] @property属性
        NSLog(@"firstObject = %d, lastObject = %@", [[arry3 firstObject] intValue], [arry3 lastObject]);
        
        //3.5 复制在原数组一个 aRange 范围的元素到一个C语言缓冲区,并返回由这些元素组成的一个新的数组
        //arry3 getObjects:(__unsafe_unretained id  _Nonnull *) range:(NSRange)
        
//         官方Demo,ARC模式下用不了
        
//         NSArray *mArray = arry3;// an array with at least six elements...;
//         id *cObject;
//         
//         NSRange range = NSMakeRange(2, 4);
//         cObject = malloc(sizeof(id) * range.length);
//         
//         [mArray getObjects:cObject range:range];
//         
//         for (int i = 0; i < range.length; i++) {
//         NSLog(@"objects: %@", cObject[i]);
//         }
//         free(cObject);
        
        //3.6 抽取原数组中 range 范围的元素并以此生成一个新的数组并返回
        NSRange range;      //创建一个 range 结构体
        range.location = 2;
        range.length   = 2;
        NSArray *arryOfArange = [arry3 subarrayWithRange:range];
        NSLog(@"arryOfArange = %@", arryOfArange);
        
        //4.数组元素的比较
        NSArray *arry4_1 = @[@1, @2, @3];
        NSArray *arry4_2 = @[@1, @2, @3];
        NSArray *arry4_3 = @[@2, @1];
        NSArray *arry4_4 = @[@4, @2, @3,@1];
        //4.1 两个数组元素完全一样才会返回YES
        [arry4_1 isEqualToArray:arry4_2] ? NSLog(@"arry4_1 & arry4_2: YES"): NSLog(@"arry4_1 & arry4_2: NO");
        [arry4_1 isEqualToArray:arry4_3] ? NSLog(@"arry4_1 & arry4_3: YES"): NSLog(@"arry4_1 & arry4_3: NO");
        [arry4_3 isEqualToArray:arry4_4] ? NSLog(@"arry4_3 & arry4_4: YES"): NSLog(@"arry4_3 & arry4_4: NO");
        
        //4.2 返回两个数组中第一个相同的元素
        NSLog(@"arry4_1 & arry4_2 : %@", [arry4_1 firstObjectCommonWithArray:arry4_2]);   //只返回index为 0 的元素 @1
        NSLog(@"arry4_1 & arry4_3 : %@", [arry4_1 firstObjectCommonWithArray:arry4_3]);   //只返回index为 1 的元素 @1
        NSLog(@"arry4_3 & arry4_4 : %@", [arry4_3 firstObjectCommonWithArray:arry4_4]);   //只返回index为 1 的元素 @2
        
        //5.向数组中增加元素
        NSArray *arry5 = [NSArray arrayWithObjects:@1,@2,@3,@4,nil];
        //5.1 返回一个由消息接收者和anObject共同组成的新数组(anObject加到新数组的末尾)
        NSLog(@"arry5 & object = %@", [arry5 arrayByAddingObject:@5]);
        
        //5.2 返回一个由消息接收者和otherArray共同组成的新数组(otherArray加到新数组的末尾)
        NSLog(@"arry5 & arry %@", [arry5 arrayByAddingObjectsFromArray:@[@"one",@"two"]]);
        
        //6.数组的排序
        NSArray *arryString = @[@"man",@"woman",@"cat",@"dog",@"fish"];
        NSArray *arryNumber = @[@5,@2,@8,@61,@1,@13];
//        6.1 使用指定方法comparator(可以自定义,也可以使用对象本身拥有的方法),返回排好序的新数组,要求:
//        (1).必须要有一个参数
//        (2).返回值必须为以下三种情况中的一种:
//            1). NSOrderedAscending  消息接收者元素 < 形参元素
//            2). NSOrderedSame       消息接收者元素 == 形参元素
//            3). NSOrderedDescending 消息接收者元素 > 形参元素
        //使用 NSString 自带的 compare: 方法
        NSArray *sortedStringArray = [arryString sortedArrayUsingSelector:@selector(compare:)];
        NSLog(@"sortedStringArray : %@", sortedStringArray);
        
        //6.2 使用指定的comparator方法,返回一个排好序的新数组,要求:
//        1).必须要有三个形式参数,前两个是数组中的元素,第三个元素是自定义形参;
//        2).返回值是NSComparisonResult类型(NSInteger也行),该类型的值就是前面方法中的NSOrderedSame等三者)
        //应用于基本数据类型
        NSArray *sortedNumberArray = [arryNumber sortedArrayUsingFunction:intSort context:nil];
        NSLog(@"sortedNumberArray : %@", sortedNumberArray);
        
        //7.给数组中的元素发送消息
        msgTest *test1 = [[msgTest alloc] init];
        msgTest *test2 = [[msgTest alloc] init];
        msgTest *test3 = [[msgTest alloc] init];
        NSArray *arryPerforms = @[test1, test2, test3];
        //7.1 为数组中的每一个元素发送一条消息(aSelector指定的方法),从数组的第一个元素依次发送到最后一个元素为止
        //注意:
        //  i: aSelector指定的方法不能有参数
        // ii: 指定的方法发生波及作用(就是改变数组之类的操作)
        //iii: 如果没有指定的方法会抛出NSInvalidArgumentException异常
        [arryPerforms makeObjectsPerformSelector:@selector(test)];
        
        //7.2 为数组中的每一个元素发送一条消息(aSelector指定的方法),从数组的第一个元素依次发送到最后一个元素为止
        //注意:
        //  i: aSelector指定的方法只能有一个参数anObject
        // ii: 指定的方法发生波及作用(就是改变数组之类的操作)
        //iii: 如果没有指定的方法会抛出NSInvalidArgumentException异常
        [arryPerforms makeObjectsPerformSelector:@selector(oneTest:) withObject:@7];
        
        //8.数组对象与文件操作
        //8.1 根据plist文件来创建数组
        NSArray *arry8_1 = [NSArray arrayWithContentsOfFile:@"/Users/windy/Desktop/OC pros/NSArrayTest/NSArrayTest/arry8.plist"];
        NSLog(@"arry8_1 --> %@", [arry8_1 description]);
        //8.2 把数组元素写进文件
        NSArray *arry8_2 = @[@"你", @[@"love",@"someone"], @"好"];
        [arry8_2 writeToFile:@"/Users/windy/Desktop/OC pros/NSArrayTest/NSArrayTest/arry8_2.plist" atomically:YES];
        //8.3 把数组元素(以“,”分隔的元素)自第一个元素至最后一个元素用separator连接起来形成字符串
        //假设separatoro "-"即:firstObject-SecondObject...-LastObject
        NSString *strTemp = [arry8_2 componentsJoinedByString:@"?"];
        NSLog(@"strTemp --> %@", strTemp);
        
        //8.4 筛选具有特定扩展名的字符串,如:“jpg”等它会自动根据扩展名进行查找不能用“.jpg”
        NSArray *arry8_4 = @[@"c.jpg",@"jpg",@"card",@"A.jpg",@"car2.jpg"];
        NSArray *fliterArray = [arry8_4 pathsMatchingExtensions:[NSArray arrayWithObject:@"jpg"]];
        NSLog(@"fliterArray : %@", fliterArray);
        NSArray *arry8_5 = @[@"t.tif",@"c.jpg",@"ee.jpg",@"card",@"A.jpg",@"car2.jpg",@"2.png",@"a.png",@"tt.doc",@"doc",@"y.tif"];
        NSArray *fliterArray2 = [arry8_5 pathsMatchingExtensions:[NSArray arrayWithObjects:@".jpg",@"png",@"doc",@"tif",nil]];
        NSLog(@"fliterArray2 : %@", fliterArray2);
    }
        //9.数组元素的遍历(block)
        NSArray *arry9 = [NSArray arrayWithObjects:@1,@2,@3,nil];
        [arry9 enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
            if (idx == 1) {
                *stop = YES;//stop是停止判断条件
            }
            //obj指代数组中的元素,如:@1
            NSLog(@"%d", [obj intValue]);
        }];
    return 0;
}