前言
@interface NSArray<__covariant ObjectType> : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
@interface NSMutableArray<ObjectType> : NSArray<ObjectType>
-
數組只能存儲 OC 對象,不能存儲 C 語言中的基本數據類型,也不能存儲 nil 。
-
Xcode 7 對系統中常用的一系列容器類型都增加了泛型支持(
),有了泛型后就可以指定容器類中對象的類型了。假如向泛型容器中加入錯誤的對象,編譯器會報警告。 __covariant:協變性,子類型可以強轉到父類型(里氏替換原則)。 __contravariant:逆變性,父類型可以強轉到子類型。
-
不指定泛型類型的對象可以和任意泛型類型轉化,但指定了泛型類型后,兩個不同類型間是不可以強轉的,假如你希望主動控制轉化關系,就需要使用泛型的協變性和逆變性修飾符。
1、不可變數組 NSArray 的創建
// 直接創建不可變數組
/*
數組成員是 id 類型,表示數組元素可以是任意的 oc 對象。
*/
NSArray *arr1 = @[@"bei", @"jing", @"huan", @"ying", @"nin"];
// 對象方法創建
NSArray *arr2 = [[NSArray alloc] init];
// 和 arr1 的地址不相同
NSArray *arr3 = [[NSArray alloc] initWithArray:arr1];
NSArray *arr4 = [[NSArray alloc] initWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil];
// 類方法創建
NSArray *arr5 = [NSArray array];
// 和 arr1 的地址不相同
NSArray *arr6 = [NSArray arrayWithArray:arr1];
// 創建只有一個元素(id)的數組
NSArray *arr7 = [NSArray arrayWithObject:@"qian"];
NSArray *arr8 = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil];
// 從 文件 創建字符串
NSString *path = [NSHomeDirectory() stringByAppendingString:@"/Desktop/test.txt"];
NSArray *arr9 = [[NSArray alloc] initWithContentsOfFile:path];
NSArray *arr10 = [NSArray arrayWithContentsOfFile:path];
// 從 Url 創建字符串
/*
file:// 文件前綴
*/
NSURL *url = [NSURL URLWithString:[@"file://" stringByAppendingString:[NSHomeDirectory()
stringByAppendingString:@"/Desktop/test.txt"]]];
NSArray *arr11 = [[NSArray alloc] initWithContentsOfURL:url];
NSArray *arr12 = [NSArray arrayWithContentsOfURL:url];
// 泛型定義
// 指明數組中存放的是 NSString 類型數據
NSArray<NSString *> *arr13 = @[@"bei", @"jing", @"huan", @"ying", @"nin"];
// 指明數組中存放的是 NSNumber 類型數據
NSArray<NSNumber *> *arr14 = @[@2, @4, @6, @8, @10];
2、數組成員個數計算
NSArray *arr = @[@"bei", @"jing", @"huan", @"ying", @"nin"];
NSUInteger length = [arr count];
3、從數組中取成員
NSArray *arr = @[@"bei", @"jing", @"huan", @"ying", @"nin"];
// []
NSArray *arr1 = arr[1];
// objectAtIndex
NSArray *arr2 = [arr objectAtIndex:2];
// subarrayWithRange
NSArray *arr3 = [arr subarrayWithRange:NSMakeRange(2, 2)];
// for...in 循環
/*
取出數組中的每個元素,分別保存在 tmp 中
*/
for (NSString *tmp in arr) {
NSLog(@"%@", tmp);
}
// id (void *) 泛型指針, 取出數組中的每個元素,分別保存在 tmp 中
for (id tmp in arr) {
NSLog(@"tmp = %@", tmp);
}
4、取數組中最后一個元素
NSArray *arr = @[@"bei", @"jing", @"huan", @"ying", @"nin"];
id lastObject1 = [arr lastObject];
id lastObject2 = arr[[arr count]-1];
5、由元素的值獲取下標
NSArray *arr = @[@"bei", @"jing", @"huan", @"ying", @"nin"];
NSUInteger index = [arr indexOfObject:@"huan"];
6、判斷數組中是否包含某個元素
NSArray *arr = @[@"bei", @"jing", @"huan", @"ying", @"nin"];
BOOL result = [arr containsObject:@"huan"];
7、數組的比較
NSArray *arr1 = @[@"bei", @"jing", @"huan", @"ying", @"nin"];
NSArray *arr2 = @[@"ni", @"hao", @"bei", @"jing"];
// isEqualToArray
// 比較兩個數組內容是否相同
BOOL bl = [arr1 isEqualToArray:arr2];
// firstObjectCommonWithArray
// 返回兩個數組中第一個相同的元素
NSString *str = [arr1 firstObjectCommonWithArray:arr2];
8、數組組合
NSArray *arr1 = @[@"bei", @"jing", @"huan", @"ying", @"nin"];
NSArray *arr2 = @[@"Users", @"JHQ0228", @"Desktop"];
// 按指定字符組合
NSString *str1 = [arr1 componentsJoinedByString:@" "];
// 按路徑組合
/*
將數組中的元素自動組合成路徑,在每個元素之間自動加上 “/”
*/
NSString *str2 = [NSString pathWithComponents:arr2];
9、可變數組 NSMutableArray 的創建
// 對象方法創建
/*
創建指定長度的數組,預先分配空間,提高效率,實際長度可大於指定長度
*/
NSMutableArray *arr1 = [[NSMutableArray alloc] initWithCapacity:0];
// 類方法創建
/*
創建指定長度的數組,預先分配空間,提高效率,實際長度可大於指定長度
*/
NSMutableArray *arr2 = [NSMutableArray arrayWithCapacity:0];
10、數組元素的添加
NSMutableArray *arr = [NSMutableArray arrayWithCapacity:0];
// addObject
// 向數組中追加一個元素
[arr addObject:@"bei"];
// addObjectsFromArray
// 追加數組
NSArray *arrAdd = @[@"dian", @"ying", @"xue", @"yuan"];
[arr addObjectsFromArray:arrAdd];
// insertObject... atIndex
// 在數組中任意位置插入一個元素
[arr insertObject:@"hao" atIndex:2];
// arrayByAddingObject
// 向數組添加一個元素,返回一個新的數組
NSArray *arr1 = [arr arrayByAddingObject:@"ma"];
11、數組元素的刪除
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"nan", @"jing", @"huan", @"ying",
@"nin", @"bei", @"jing", @"ni", @"hao", nil];
// 刪除指定下標的元素
[arr removeObjectAtIndex:2];
// 刪除指定元素,刪除所有指定元素
[arr removeObject:@"ying"];
// 刪除指定元素
[arr removeObjectIdenticalTo:@"nan"];
// 刪除指定范圍的元素
NSRange range = {2,1};
[arr removeObjectsInRange:range];
// 刪除最后一個元素
[arr removeLastObject];
// 刪除所有元素
[arr removeAllObjects];
12、數組元素的替換
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"nan", @"jing", @"hao", nil];
// 替換指定下標元素
[arr replaceObjectAtIndex:1 withObject:@"ren"];
13、數組元素的交換
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"bei", @"jing", @"nin", @"hao", nil];
[arr exchangeObjectAtIndex:0 withObjectAtIndex:1];
14、數組元素的修改
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"bei", @"jing", @"nin", @"hao", nil];
// 修改整個數組(覆蓋重寫)
[arr setArray:@[@"bei", @"jing", @"huan", @"ying", @"nin"]];
// 修改數組中的某個元素
arr[3] = @"huan";
15、給數組里的所有元素發送一個消息
Student *stu1 = [[Student alloc] init];
Student *stu2 = [[Student alloc] init];
Student *stu3 = [[Student alloc] init];
NSArray *arr = [NSArray arrayWithObjects:stu1, stu2, stu3, nil];
// 發送消息
[arr makeObjectsPerformSelector:@selector(studentTest)];
16、數組的遍歷
-
用 for 循環遍歷
NSArray * array = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil]; for (int i = 0; i < [array count]; i ++) { NSLog(@"%@", array[i]); }
-
用 for...in 循環遍歷
NSArray *array = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil]; // id (void *) 泛型指針, 取出數組中的每個元素,分別保存在 tmp 中 for (id tmp in array) { NSLog(@"%@", tmp); } // 取出數組中的每個元素,分別保存在 tmp 中 for (NSString *tmp in array) { NSLog(@"%@", tmp); }
-
用 block 循環遍歷
NSArray *array = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil]; [array enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { // obj == array[i],idx == i NSLog(@"%@", obj); if ([obj isEqual: @"huan"]) { // 停止遍歷 *stop = YES; } }];
-
用迭代器遍歷
NSArray *array = [NSArray arrayWithObjects:@"bei", @"jing", @"huan", @"ying", @"nin", nil]; // 獲取數組的正序迭代器 NSEnumerator *enu1 = [array objectEnumerator]; // 獲取數組的反序迭代器 NSEnumerator *enu2 = [array reverseObjectEnumerator]; id obj = nil; // 正序,獲取下一個需要遍歷的元素 while (obj = [enu1 nextObject]) { NSLog(@"%@", obj); } // 反序,獲取下一個需要遍歷的元素 while (obj = [enu2 nextObject]) { NSLog(@"%@", obj); }
-
條件遍歷
// 1.indexesOfObjectsPassingTest NSArray *array = [NSArray arrayWithObjects:@3, @8, @17, @2, @25, @6, @89, nil]; NSIndexSet *indexSet = [array indexesOfObjectsPassingTest:^BOOL(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { // 遍歷數組,找出數組中所有大於 10 的元素的位置 return [obj intValue] > 10 ? : NO; }]; [indexSet enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL * _Nonnull stop) { // 輸出所有大於 10 的元素值 NSLog(@"%@", array[idx]); }]; // 2.indexOfObjectPassingTest NSUInteger index = [array indexOfObjectPassingTest:^BOOL(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) { // 遍歷數組,找出數組中第一個大於 10 的元素的位置 return [obj intValue] > 10 ? : NO; }]; // 輸出第一個大於 10 的元素值 NSLog(@"%@", array[index]);
17、數組排序
-
冒泡排序
NSMutableArray *arr = [NSMutableArray arrayWithObjects:@"sunday", @"sunny", @"summer", @"sun", nil]; for (int i = 0; i < [arr count] - 1; i++) { for (int j = 0; j < [arr count] - 1 - i; j++) { // 大小判斷 arr[j] > arr[j + 1] if ([arr[j] compare:arr[j + 1]] == NSOrderedDescending) { // 位置交換 [arr exchangeObjectAtIndex:j withObjectAtIndex:(j + 1)]; } } }
-
用指定的方法排序
// 1.用指定的方法排序,可變數組排序 NSMutableArray *arr1 = [NSMutableArray arrayWithObjects:@"sunday", @"sunny", @"summer", @"sun", nil]; // 原數組的順序改變,指定元素的比較方法:compare:,默認排序方式為升序排列 [arr1 sortUsingSelector:@selector(compare:)]; // 使排序結果 降序 排列 NSEnumerator *enu = [arr1 reverseObjectEnumerator]; id obj = nil; while (obj = [enu nextObject]) { // 排序后的結果為降序 NSLog(@"%@", obj); } // 2.用指定的方法排序,不可變數組排序 NSArray *arr2 = [NSArray arrayWithObjects:@"sunday", @"sunny", @"summer", @"sun", nil]; // 返回一個排好的數組,原數組的順序不變,指定元素的比較方法:compare: NSArray *arr3 = [arr2 sortedArrayUsingSelector:@selector(compare:)]; // 3.用指定的方法排序,自定義類 // People.h #import <Foundation/Foundation.h> @interface People : NSObject // 名 @property (nonatomic, retain) NSString *firstname; // 姓 @property (nonatomic, retain) NSString *lastname; + (id)peopleWithFirstname:(NSString *)firstname lastname:(NSString *)lastname; // 返回值類型為 NSComparisonResult - (NSComparisonResult)comparePeople:(People *)peop; @end // People.m #import "People.h" @implementation People + (id)peopleWithFirstname:(NSString *)firstname lastname:(NSString *)lastname { People * peop = [[People alloc] init]; peop.lastname = lastname; peop.firstname = firstname; return peop; } - (NSComparisonResult)comparePeople:(People *)peop { // 先按照姓排序 NSComparisonResult result = [self.lastname compare: peop.lastname]; if (result == NSOrderedSame) { // 如果有相同的姓,就比較名字 result = [self.firstname compare: peop.firstname]; } return result; } -(NSString *)description{ return [NSString stringWithFormat:@"%@ %@", self.firstname, self.lastname]; } @end // main.m #import "People.h" People *peop1 = [People peopleWithFirstname:@"MingJie" lastname:@"Li"]; People *peop2 = [People peopleWithFirstname:@"LongHu" lastname:@"Huang"]; People *peop3 = [People peopleWithFirstname:@"LianJie" lastname:@"Li"]; People *peop4 = [People peopleWithFirstname:@"Jian" lastname:@"Xiao"]; // 1.用指定的方法排序,可變數組排序 NSMutableArray *array1 = [NSMutableArray arrayWithObjects:peop1, peop2, peop3, peop4, nil]; // 原數組的順序改變 [array1 sortUsingSelector:@selector(comparePeople:)]; // 2.用指定的方法排序,不可變數組排序 NSArray *array2 = [NSArray arrayWithObjects:peop1, peop2, peop3, peop4, nil]; // 返回一個排好的數組,原數組的順序不變 NSArray *array3 = [array2 sortedArrayUsingSelector:@selector(comparePeople:)];
-
用 Block 排序
// 1.利用 block 進行排序,可變數組排序 NSMutableArray *arr1 = [NSMutableArray arrayWithObjects:@"sunday", @"sunny", @"summer", @"sun", nil]; [arr1 sortUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { // 指定比較的方法,兩個元素值比較 NSComparisonResult result = [obj1 compare:obj2]; // 返回比較的結果 return result; }]; // 2.利用 block 進行排序,不可變數組排序 NSArray *arr2 = [NSArray arrayWithObjects:@"sunday", @"sunny", @"summer", @"sun", nil]; // 返回一個排好的數組 NSArray *arr3 = [arr2 sortedArrayUsingComparator:^NSComparisonResult(id _Nonnull obj1, id _Nonnull obj2) { // 指定比較的方法,兩個元素值比較 NSComparisonResult result = [obj1 compare:obj2]; // 返回比較的結果 return result; }]; // 3.利用 block 進行排序,自定義類 // People1.h #import <Foundation/Foundation.h> @interface People1 : NSObject // 名 @property (nonatomic, retain) NSString *firstname; // 姓 @property (nonatomic, retain) NSString *lastname; + (id)peopleWithFirstname:(NSString *)firstname lastname:(NSString *)lastname; @end // People1.m #import "People1.h” @implementation People1 + (id)peopleWithFirstname:(NSString *)firstname lastname:(NSString *)lastname { People1 * peop = [[People1 alloc] init]; peop.lastname = lastname; peop.firstname = firstname; return peop; } -(NSString *)description{ return [NSString stringWithFormat:@"%@ %@", self.firstname, self.lastname]; } @end // main.m #import "People1.h” People1 *peop1 = [People1 peopleWithFirstname:@"MingJie" lastname:@"Li"]; People1 *peop2 = [People1 peopleWithFirstname:@"LongHu" lastname:@"Huang"]; People1 *peop3 = [People1 peopleWithFirstname:@"LianJie" lastname:@"Li"]; People1 *peop4 = [People1 peopleWithFirstname:@"Jian" lastname:@"Xiao"]; // 1.利用 block 進行排序,可變數組排序 NSMutableArray *array1 = [NSMutableArray arrayWithObjects:peop1, peop2, peop3, peop4, nil]; [array1 sortUsingComparator:^NSComparisonResult(People1 * _Nonnull obj1, People1 * _Nonnull obj2) { // 先按照姓排序 NSComparisonResult result = [obj1.lastname compare:obj2.lastname]; if (result == NSOrderedSame) { // 如果有相同的姓,就比較名字 result = [obj1.firstname compare:obj2.firstname]; } return result; }]; // 2.利用 block 進行排序,不可變數組排序 NSArray *array2 = [NSArray arrayWithObjects:peop1, peop2, peop3, peop4, nil]; NSArray *array3 = [array2 sortedArrayUsingComparator:^NSComparisonResult(People1 * _Nonnull obj1, People1 * _Nonnull obj2) { // 先按照姓排序 NSComparisonResult result = [obj1.lastname compare:obj2.lastname]; if (result == NSOrderedSame) { // 如果有相同的姓,就比較名字 result = [obj1.firstname compare:obj2.firstname]; } return result; }];
-
按描述器排序
// Book.h #import <Foundation/Foundation.h> @interface Book : NSObject @property (nonatomic, retain) NSString *name; + (id)bookWithName:(NSString *)name; @end // Book.m #import "Book.h" @implementation Book + (id)bookWithName:(NSString *)name { Book *book = [[Book alloc] init]; book.name = name; return book; } @end // People2.h #import <Foundation/Foundation.h> @class Book; @interface People2 : NSObject // 名 @property (nonatomic, retain) NSString *firstname; // 姓 @property (nonatomic, retain) NSString *lastname; // 書 @property (nonatomic, retain) Book *book; + (id)peopleWithFirstname:(NSString *)firstname lastname:(NSString *)lastname bookName:(NSString *)bookName; @end // People2.m #import "People2.h" #import "Book.h" @implementation People2 + (id)peopleWithFirstname:(NSString *)firstname lastname:(NSString *)lastname bookName:(NSString *)bookName { People2 *peop = [[People2 alloc] init]; peop.lastname = lastname; peop.firstname = firstname; peop.book = [Book bookWithName:bookName]; return peop; } - (NSString *)description{ return [NSString stringWithFormat:@"%@ %@, bookName: %@", self.firstname, self.lastname, self.book.name]; } @end // main.m #import "People2.h" People2 *peop1 = [People2 peopleWithFirstname:@"MingJie" lastname:@"Li" bookName:@"book1"]; People2 *peop2 = [People2 peopleWithFirstname:@"LongHu" lastname:@"Huang" bookName:@"book2"]; People2 *peop3 = [People2 peopleWithFirstname:@"LianJie" lastname:@"Li" bookName:@"book2"]; People2 *peop4 = [People2 peopleWithFirstname:@"Jian" lastname:@"Xiao" bookName:@"book1"]; // 先按照書名進行排序 /* 這里的 key 寫的是 @property 的名稱 */ NSSortDescriptor *bookNameDesc = [NSSortDescriptor sortDescriptorWithKey:@"book.name" ascending:YES]; // 再按照姓進行排序 NSSortDescriptor *lastnameDesc = [NSSortDescriptor sortDescriptorWithKey:@"lastname" ascending:YES]; // 再按照名進行排序 NSSortDescriptor *firstnameDesc = [NSSortDescriptor sortDescriptorWithKey:@"firstname" ascending:YES]; // 1.按描述器排序,可變數組排序 NSMutableArray *array1 = [NSMutableArray arrayWithObjects:peop1, peop2, peop3, peop4, nil]; // 按順序添加排序描述器 NSMutableArray *descs1 = [NSMutableArray arrayWithObjects:bookNameDesc, lastnameDesc, firstnameDesc, nil]; [array1 sortUsingDescriptors:descs1]; // 2.按描述器排序,不可變數組排序 NSArray *array2 = [NSArray arrayWithObjects:peop1, peop2, peop3, peop4, nil]; // 按順序添加排序描述器 NSArray *descs2 = [NSArray arrayWithObjects:bookNameDesc, lastnameDesc, firstnameDesc, nil]; NSArray *array3 = [array2 sortedArrayUsingDescriptors:descs2];