iOS 开发:Foundation 框架详尽总结之『数组类』

本文对Foundation框架中的数组类(NSArray、MutableNSArray)的使用做一个详细的总结。

1. NSArray

1. NSArray 介绍

  • NSArray 是 OC 中的数组类,开发中建议尽量使用 NSArray 替代 C 语言中的数组
  • C 语言中虽然也有数组,但在开发的过程中存在一些弊端
    • int array[4] = {10, 89, 27, 76};
    • 只能存放一种类型的数据(类型必须一致)
    • 不能很方便地动态添加数组元素、不能很方便地动态删除数组元素(长度固定)
  • Foundation数组是有序的对象集合
  • 一般情况下,一个数组中的元素都是一种特定类型,但不是必需的

2. NSArray 的创建方式

  • + (instancetype)array;
  • + (instancetype)arrayWithObject:(id)anObject;
  • + (instancetype)arrayWithObjects:(id)firstObj, ...;
  • + (instancetype)arrayWithArray:(NSArray *)array;
  • + (id)arrayWithContentsOfFile:(NSString *)path;
  • + (id)arrayWithContentsOfURL:(NSURL *)url;

3. NSArray 的使用注意事项

  • NSArray直接使用NSLog()作为字符串输出时是小括号括起来的形式。
  • 只能存放任意OC对象, 并且是有顺序的
  • 不能存储非OC对象, 比如int\float\double\char\enum\struct等
  • NSArray中不能存储nil,因为NSArray认为nil是数组的结束(nil是数组元素结束的标记)。nil就是0。0也是基本数据类型,不能存放到NSArray中。
  • 它是不可变的,一旦初始化完毕后,它里面的内容就永远是固定的,不能删除里面的元素,也不能再往里面添加元素
NSArray *arr = [NSArray arrayWithObjects:@"abc", nil ,@"edf",@"hij", nil];
NSLog(@"%@", arr);

输出结果:
(
    abc
)

4. NSArray 的常用方法

// 先定义一个数组,用于举例说明下面各个常用方法如何使用
NSArray *arr = [NSArray arrayWithObjects:@"abc",@"edf",@"hij", nil];
  • 获取集合元素个数- (NSUInteger)count;
NSLog(@"count = %lu",[arr count]);

输出结果:count = 3
  • 获得index位置的元素- (id)objectAtIndex:(NSUInteger)index;
NSLog(@"arr[1] = %@",[arr objectAtIndex:1]);

输出结果:arr[1] = edf
  • 是否包含某一个元素- (BOOL)containsObject:(id)anObject;
if ([arr containsObject:@"klm"]) {
    NSLog(@"arr中包含klm");
} else {
    NSLog(@"arr中不包含klm");
}

输出结果:arr中不包含klm

  • 返回第一个元素- (id)firstObject;
NSLog(@"first = %@",[arr firstObject]);

输出结果:first = abc
  • 返回最后一个元素- (id)lastObject;
NSLog(@"last = %@",[arr lastObject]);

输出结果:last = hij
  • 查找anObject元素在数组中的位置(如果找不到,返回-1)- (NSUInteger)indexOfObject:(id)anObject;
NSLog(@"index = %lu",[arr indexOfObject:@"hij"]);

输出结果:index = 2
  • 在range范围内查找anObject元素在数组中的位置- (NSUInteger)indexOfObject:(id)anObject inRange:(NSRange)range;
NSRange range = {1,2};
NSLog(@"index = %lu",[arr indexOfObject:@"edf" inRange:range]);

输出结果:index = 1

5. NSArray 的简写形式

  • 自从2012年开始,Xcode的编译器多了很多自动生成代码的功能,使得OC代码更加精简
  • 之前数组的创建方式
[NSArray arrayWithObjects:@"Jack", @"Rose", @"Jim", nil];

  • 现在数组的创建方式
@[@"Jack", @"Rose", @"Jim"];
  • 之前数组元素的访问方式
[array objectAtIndex:index];
  • 现在数组元素的访问方式
array[index];

6. NSArray 遍历

1.NSArray的下标遍历

NSArray *arr = @[@"abc", @"edf", @"hij"];
for (int i = 0; i < arr.count; ++i) {
    NSLog(@"arr[%i] = %@", i, arr[i]);
}

输出结果:
arr[0] = abc
arr[1] = edf
arr[2] = hij

2. NSArray 的快速遍历

NSArray *arr = @[@"abc", @"edf", @"hij"];    
// OC数组可以使用OC中的增强for循环来遍历
// 逐个取出arr中的元素,将取出的元素赋值给obj
// 注意:obj的类型可以根据数组中元素的类型来写,不一定要写NSObject
for (NSString *obj in arr) {
    NSLog(@"obj = %@", obj);
}

输出结果:
obj = abc
obj = edf
obj = hij

3. NSArray 使用 block 进行遍历

NSArray *arr = @[@"abc", @"edf", @"hij"];      
// 使用OC数组的迭代器来遍历
// 每取出一个元素就会调用一次block
// 每次调用block都会将当前取出的元素和元素对应的索引传递给我们
// obj就是当前取出的元素, idx就是当前元素对应的索引
[arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
    if (idx == 1) {
        *stop = YES;  // stop用于控制什么时候停止遍历
    }
    NSLog(@"obj = %@, idx = %lu", obj, idx);
}];

输出结果:
obj = abc, idx = 0
obj = edf, idx = 1

4. NSArray 给所有元素发消息

  • 让集合里面的所有元素都执行aSelector这个方法
    • - (void)makeObjectsPerformSelector:(SEL)aSelector;
    • - (void)makeObjectsPerformSelector:(SEL)aSelector withObject:(id)argument;
// 让数组中所有对象执行这个方法
// 注意:如果数组中的对象没有这个方法会报错,需要实现该方法
//    [arr makeObjectsPerformSelector:@selector(say)];
[arr makeObjectsPerformSelector:@selector(eat:) withObject:@"bread"];

7. NSArray 排序

1. NSArray 排序

  • Foundation自带类排序
    • 使用compare方法对数组中的元素进行排序, 那么数组中的元素必须是Foundation框架中的对象, 也就是说不能是自定义对象
NSArray *arr = @[@10,@9,@1,@19];
NSLog(@"排序前: %@", arr);
NSArray *newArr = [arr sortedArrayUsingSelector:@selector(compare:)];
NSLog(@"排序后: %@", newArr);

输出结果:
排序前: (
    10,
    9,
    1,
    19
)
排序后: (
    1,
    9,
    10,
    19
)
  • 自定义类排序

定义一个Person类,Person拥有age属性。

#import <Foundation/Foundation.h>

@interface Person : NSObject
@property (nonatomic, assign) int age;
@end

因为不能使用compare:方法对自定义对象进行排序,我们通过执行区块block对自定义类进行排序,下面是按照age的大小对Person进行排序

Person *p1 = [Person new];
p1.age = 10;
Person *p2 = [Person new];
p2.age = 20;    
Person *p3 = [Person new];
p3.age = 5;
Person *p4 = [Person new];
p4.age = 7;

NSArray *arr = @[p1, p2, p3, p4];
NSLog(@"排序前: %@", arr);
// 按照人的年龄进行排序
// 该方法默认会按照升序排序
NSArray *newArr = [arr sortedArrayWithOptions:NSSortStable usingComparator:^NSComparisonResult(Person *obj1, Person *obj2) {
// 每次调用该block都会取出数组中的两个元素给我们
return obj1.age > obj2.age;    // 升序
//    return obj1.age < obj2.age;    // 降序
}];
NSLog(@"排序后: %@", newArr);

输出结果:
排序前: (
    "age = 10",
    "age = 20",
    "age = 5",
    "age = 7"
)
排序后: (
    "age = 5",
    "age = 7",
    "age = 10",
    "age = 20"
)

8. NSArray 文件读写

1. NSArray 数据写入到文件中

NSArray *arr = @[@"abc", @"def", @"hij", @"klm"];

BOOL flag = [arr writeToFile:@"/Users/Walkers/Desktop/test.plist" atomically:YES];
NSLog(@"flag = %i", flag);

输出结果:flag = 1

2. 从文件中读取数据到 NSArray 中

NSArray *newArr = [NSArray arrayWithContentsOfFile:@"/Users/Walkers/Desktop/test.plist"];
NSLog(@"newArr = %@", newArr);

输出结果:
newArr = (
    abc,
    def,
    hij,
    klm
)

9. NSArray 与字符串之间的转换

1. 把数组元素链接成字符串

  • 用 separator 作拼接符将数组元素拼接成一个字符串- (NSString *)componentsJoinedByString:(NSString *)separator;
NSArray *arr = @[@"abc", @"edf", @"hij", @"klm"];

NSString *res = [arr componentsJoinedByString:@"*"];
NSLog(@"res = %@", res);

输出结果:res = abc*edf*hij*klm

2. 字符串分割方法

  • 将字符串用 separator 作为分隔符切割成数组元素- (NSArray *)componentsSeparatedByString:(NSString *)separator;
NSString *str = @"abc-edf-hij-klm";

NSArray *arr = [str componentsSeparatedByString:@"-"];
NSLog(@"arr = %@", arr);

输出结果:
arr = (
    abc,
    edf,
    hij,
    klm
)

2. NSMutableArray

1. NSMutableArray 介绍

  • NSMutableArray是NSArray的子类
  • NSArray是不可变的,一旦初始化完毕后,它里面的内容就永远是固定的,不能删除里面的元素,也不能再往里面添加元素
  • NSMutableArray是可变的,数组元素的个数未指定并且可以根据需要增长,随时可以往里面添加\更改\删除元素

2. NSMutableArray 基本用法

  • 创建空数组
NSMutableArray *arr = [NSMutableArray array];
  • 创建数组,并且指定长度为5,此时也是空数组
NSMutableArray *arr = [[NSMutableArray alloc] initWithCapacity:5];
  • 创建一个数组,包含两个元素
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"1",@"2", nil];
  • 调用对象方法创建数组
NSMutableArray *arr = [[NSMutableArray alloc] initWithObjects:@"1",@"2", nil];
  • 添加一个元素- (void)addObject:(id)object;
NSMutableArray *arr = [NSMutableArray array];

[arr addObject:@"abc"];
NSLog(@"%@",arr);

输出结果:
(
    abc
)
  • 添加otherArray的全部元素到当前数组中- (void)addObjectsFromArray:(NSArray *)array;
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"abc", nil];

[arr addObjectsFromArray:@[@"def",@"hij"]];
NSLog(@"%@",arr);

输出结果:
(
    abc,
    def,
    hij
)
  • 在index位置插入一个元素- (void)insertObject:(id)anObject atIndex:(NSUInteger)index;
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"abc", @"hij",nil];

[arr insertObject:@"def" atIndex:1];
NSLog(@"%@",arr);

输出结果:
(
    abc,
    def,
    hij
)
  • 删除最后一个元素- (void)removeLastObject;
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"abc",@"def",@"hij",nil];

[arr removeLastObject];
NSLog(@"%@",arr);

输出结果:
(
    abc,
    def
)
  • 删除所有的元素- (void)removeAllObjects;
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"abc",@"def",@"hij",nil];

[arr removeAllObjects];
NSLog(@"%@",arr);

输出结果:
(
)
  • 删除index位置的元素- (void)removeObjectAtIndex:(NSUInteger)index;

NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"abc",@"def",@"hij",nil];
[arr removeObjectAtIndex:1];

NSLog(@"%@",arr);

输出结果:
(
    abc,
    hij
)

  • 删除特定的元素- (void)removeObject:(id)object;
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"abc",@"def",@"hij",nil];

[arr removeObject:@"abc"];
NSLog(@"%@",arr);

输出结果:
(
    def,
    hij
)
  • 删除range范围内的所有元素- (void)removeObjectsInRange:(NSRange)range;
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"abc",@"def",@"hij",nil];
NSRange range = NSMakeRange(1, 2);

[arr removeObjectsInRange:range];
NSLog(@"%@",arr);

输出结果:
(
    abc
)
  • 用anObject替换index位置对应的元素- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(id)anObject;
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"abc",@"def",@"hij",nil];

[arr replaceObjectAtIndex:1 withObject:@"xyz"];
NSLog(@"%@",arr);

输出结果:
(
    abc,
    xyz,
    hij
)
  • 交换idx1和idx2位置的元素- (void)exchangeObjectAtIndex:(NSUInteger)idx1 withObjectAtIndex:(NSUInteger)idx2;
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"abc",@"def",@"hij",nil];

[arr exchangeObjectAtIndex:0 withObjectAtIndex:2];
NSLog(@"%@",arr);

输出结果:
(
    hij,
    def,
    abc
)

3. NSMutableArray 错误用法

  • 不可以使用@[]创建可变数组

NSMutableArray *array = @[@"lnj", @"lmj", @"jjj"];

// 报错, 本质还是不可变数组
[array addObject:@“Peter”];
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,602评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,442评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,878评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,306评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,330评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,071评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,382评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,006评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,512评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,965评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,094评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,732评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,283评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,286评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,512评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,536评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,828评论 2 345

推荐阅读更多精彩内容