2.集合
目前来看类型只能是Objective-C object或者block。
NSArray特点: 一旦创建成功,内容不可改变,只能存放OC对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 //1)创建一个空数组 NSArray *arr1 = [NSArray array]; //2)创建数组,只有一个元素 NSArray *arr2 = [NSArray arrayWithObject:@"1"]; //3)创建数组,有多个元素 // nil 表示数组赋值结束 // 常见写法 NSArray *arr3 = [NSArray arrayWithObjects:@"one",@"two",@1, nil]; NSLog(@"arr3 = %@",arr3); //4)调用对象方法,创建数组 //nil Nil NULL NSNULL NSArray *arr4 = [[NSArray alloc] initWithObjects:@"three",[NSNull null],@"four", nil]; NSLog(@"arr4 = %@",arr4); //5)用一个数组可以创建另外一个数组,修改一个数组中的数据不影响另一个数组。 NSArray *arr5 = [NSArray arrayWithArray:arr3];
常用方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 NSArray* arr3 = [NSArray arrayWithObjects:@"one", @"two", @1, @"three", nil]; NSLog(@"arr3 = %@", arr3); //1)获取数组的长度 count获取数组的元素的个数 NSLog(@"%ld", arr3.count); //2)根据下标,获取下标对应的对象 NSLog(@"%@", [arr3 objectAtIndex:3]); //3)返回元素的下标 NSUInteger loc = [arr3 indexOfObject:@"three"]; NSLog(@"%ld", loc); //4)数组中是否包含了某个元素 if ([arr3 containsObject:@"four"]) { NSLog(@"包含此元素"); } else { NSLog(@"不包含"); } NSLog(@"arr5 = %@", arr5);
简化形式
1 2 3 4 5 6 7 8 9 10 11 12 //用简化的方式,来定义和访问数组元素 //1)用简化的方式,定义数组 //格式: @[ 数组元素 ] NSArray* arr = @[ @"1", @"one", @"3", @4, @"ONE" ]; NSLog(@"arr = %@", arr); NSString* str = [arr objectAtIndex:2]; NSLog(@"%@", str); //2)用简化的方式访问数组元素 str = arr[1]; //C语言形式的数组元素访问 NSLog(@"%@", str);
遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 //定义一个数组 NSArray* arr = @[ @"one", @"two", @"three", @"four" ]; //对数组进行遍历 //1) 普通的方式,通过下标访问 for (int i = 0; i < arr.count; i++) { NSLog(@"-> %@", arr[i]); } //2) 快速枚举法 for循环的增强形式 for (NSString* str in arr) { NSLog(@"---> %@", str); } //3) 使用block的方式,进行访问 // 数组元素 元素下标 是否停止 //stop:YES 会停止, stop:NO 不会停止 [arr enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL* stop) { if (idx == 2) { *stop = YES; //停止 // break; } else { NSLog(@"idx = %ld,obj = %@", idx, obj); } }]; //补充:OC1.0中的方法 id obj2; NSEnumerator* enumerator = [arr objectEnumerator]; while ((obj2 = [enumerator nextObject]) != nil) { NSLog(@"%@ ", obj2); } ``` 5. 读写文件: - 写入
NSArray* array = [NSArray arrayWithObjects:@”one”, @”zbz”, @”cgx”, @”sb”, @”cjk”, @”senni”, nil]; //把NSArray 中的内容,写入到文件中 //arr.plist 一种特殊的文件格式 BOOL isWrite = [array writeToFile:@”/Users/zhaoxiaohu/Desktop/arr.xml” atomically:YES];
if (isWrite) {
NSLog(@"写入成功");
}
//从文件中,读取一个数组信息 NSArray *readArr = [NSArray arrayWithContentsOfFile:@”/Users/zhaoxiaohu/Desktop/arr.xml”];
NSLog(@”readArr = %@”,readArr);
1 2 3 4 6. NSArray与字符串: - 把数组拼接成为字符串
//定义一个数组 NSArray *arr = @[@1,@2,@3,@4];
//1)需求: 把数组中的元素用 “-“ 连接起来 // [数组 componentsJoinedByString @”分隔符”]; // 1-2-3-4 NSString *str = [arr componentsJoinedByString:@”-“]; NSLog(@”str = %@”,str);
//2) 给一个字符串,分割成一个数组 // 400-800-12580 //取得 400 12580 800 NSString *str2 = @”400-800-12580”; NSArray *arr2 = [str2 componentsSeparatedByString:@”-“]; NSLog(@”%@”,[arr2 firstObject]); NSLog(@”%@”,[arr2 lastObject]); NSLog(@”%@”,arr2[1]); 1 2 3 4 5 6 7 8 - #### NSMutableArray - NSArray子类,内容可变,其余很多操作与NSArray一样。 ``` NSMutableArray<NSNumber*>* mutablearr = [NSMutableArray array]; [mutablearr addObject:[NSNumber numberWithInt:1]];
虽然有arrayWithCapacity这个方法,但是内容是可以超出设定的值的。应该仅仅是申请内存的需要,毕竟可变长度对于内存操作上比较麻烦。
NSDictionary与NSMutableDictionary 字典的核心在于key和value。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 //创建字典 //1、使用类方法创建字典 // 字典初始化后,内部是无序的 NSDictionary* dict1 = [NSDictionary dictionaryWithObjectsAndKeys:@"zhangsan", @"zs", @"lisi", @"ls", nil]; //获取字典的长度 NSLog(@"%ld", dict1.count); //根据key获取 value 只获取zs NSString* s = [dict1 objectForKey:@"zs"]; NSLog(@"%@", s); //2、快速创建字典 @{key:value,key1:value1} // 在字典中,key值是不能够重复的,重复的时候不会报错 // 重复的只保留一个(第一次出现的那个) NSDictionary* dict2 = @{ @"zs" : @"zhangsan", @"ls" : @"lisi", @"zs" : @"fengjie" }; NSLog(@"%@", dict2); //3、遍历 NSLog(@"获取所有keys的遍历"); NSArray* keys = [dict2 allKeys]; for (NSInteger i = 0; i < keys.count; i++) { NSLog(@"key = %@ value = %@", (NSString*)keys[i], [dict2 objectForKey:keys[i]]); } NSLog(@"NSEnumerator遍历"); id key; NSEnumerator* enumerator = [dict2 keyEnumerator]; while ((key = [enumerator nextObject]) != nil) { NSLog(@"key = %@ value = %@", (NSString*)key, [dict2 objectForKey:key]); } NSLog(@"快速遍历"); for (id key in dict2) { NSLog(@"key = %@ value = %@", (NSString*)key, dict2[key]); } NSLog(@"block遍历"); [dict2 enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL* _Nonnull stop) { NSLog(@"key = %@ value = %@", key, obj); }]; //4、可变的字典 NSMutableDictionary* mDic = [NSMutableDictionary dictionaryWithDictionary:dict1]; //4.1 移除数据 [mDic setValue:nil forKey:@"zs"]; [mDic removeObjectForKey:@"ls"]; [mDic removeAllObjects]; // [mDic removeObjectForKey:<#(nonnull id)#>]; //4.2 添加数据 [mDic setObject:@"wei" forKey:@"hua"]; [mDic setValue:@"xing" forKey:@"zhong"]; //4.3 改变数据 [mDic setObject:@"lisi2222" forKey:@"ls"]; NSLog(@"遍历NSMutableDictionary"); [mDic enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL* _Nonnull stop) { NSLog(@"key = %@ value = %@", key, obj); }];
注意setValue:forKey:这个方法,既可以添加数据也可以移除数据(当value是nil时)。
1 2 3 /* Send -setObject:forKey: to the receiver, unless the value is nil, in which case send -removeObjectForKey:. */ - (void)setValue:(nullable ObjectType)value forKey:(NSString *)key;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 在Foundation框架中,提供了NSSet类,它是一组单值对象的集合,且NSSet实例中元素是无序,同一个对象只能保存一个。 一.不可变集合NSSet 1.NSSet的初始化 创建一个集合 NSSet *set1 = [[NSSet alloc] initWithObjects:@"one", @"two", nil]; 通过数组的构建集合 NSArray *array = [NSArrayWithObjects:@"1", @"2", @"3", nil]; NSSet *set2 = [[NSSet alloc] initWithArray:array]; 通过已有集合构建集合 NSSet *set3 = [[NSSet alloc] initWithSet:set2]; 2.NSSet常用方法 集合中对象的个数 int count = [set3 count]; 以数组的形式返回集合中所有的对象 NSArray *allObjects = [set3 allObjects]; 返回集合中的任意一个对象 id object = [set3 anyObject]; 判断两个集合的元素中有包含的对象,包含返回YES,否则为NO BOOL isContain = [set4 containsObject:@"2"]; 判断两个集合的元素是否有相等的对象,存在返回YES,否则为NO BOOL isIntersect = [set4 intersectsSet:set2]; 判断两个集合的元素是否完全匹配,匹配返回YES,否则为NO BOOL isEqual = [set4 isEqualToSet:set5]; 集合4是否是集合5的子集合,如果是返回YES,否则为NO BOOL isSubset = [set4 isSubsetOfSet:set5]; 创建一个新的集合2,集合2有两个对象 NSSet *set1 = [NSSet setWithObjects:@"a",nil]; NSSet *set2 = [set1 setByAddingObject:@"b"]; 通过已有的两个集合,创建新的一个集合 NSSet *set7 = [NSSet setWithObjects:@"a",nil]; NSSet *set8 = [NSSet setWithObjects:@"z",nil]; NSSet *set9 = [set7 setByAddingObjectsFromSet:set8]; 通过已有的集合和数组对象,创建一个新的集合 NSArray *array = [NSArray arrayWithObjects:@"a",@"b",@"c",nil]; NSSet *set10 = [NSSet setWithObjects:@"z",nil]; NSSet *set11 = [set10 setByAddingObjectsFromArray:array]; 二、可变集合NSMutableSet 常用方法 创建一个空的集合 NSMutableSet *set1 = [NSMutableSet set]; NSMutableSet *set2 = [NSMutableSet setWithObjects:@"1",@"2",nil]; NSMutableSet *set3 = [NSMutableSet setWithObjects:@"a",@"2",nil]; 集合2减去集合3中的元素,集合2最后元素只有1个 [set2 minusSet:set3]; 集合2与集合3中元素的交集,集合2最后元素只有1个 [set2 intersectSet:set3]; 集合2与集合3中的元素的并集,集合2最后元素只有3个 [set2 unionSet:set3]; 将空集合1设置为集合3中的内容 [set1 setSet:set3]; 根据数组的内容删除集合中的对象 [set2 addObjectsFromArray:array]; [set2 removeObject:@"1"]; [set]2 removeAllObjects];
1 2 3 4 NSMutableArray* mutablearr = [NSMutableArray arrayWithArray:@[ @9, @8 ]]; [mutablearr addObject:[NSNumber numberWithInt:1]]; [mutablearr addObject:[NSNumber numberWithInt:2]]; [mutablearr addObject:@1];
1 2 3 4 5 6 7 8 9 10 //将NSString 对象存储到 NSUserDefaults 中 NSString *passWord = @"1234567"; NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; [user setObject:passWord forKey:@"userPassWord"]; 将数据取出也很简单,只需要取出key 对应的值就好了,代码如下: NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; NSString *passWord = [ user objectForKey:@"userPassWord"];
注意:对相同的Key赋值约等于一次覆盖,要保证每一个Key的唯一性
<font color=red>值得注意的是:</font>
NSUserDefaults 存储的对象<font color=red>全是不可变的</font>
(这一点非常关键,弄错的话程序会出bug),例如,如果我想要存储一个 NSMutableArray 对象,我必须先创建一个不可变数组(NSArray)再将它存入NSUserDefaults中去,代码如下:
1 2 3 4 5 NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:@"123",@"234", nil]; NSArray * array = [NSArray arrayWithArray:mutableArray]; NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; [user setObject:array forKey:@"记住存放的一定是不可变的"];
取出数据是一样的,想要用NSUserDefaults中的数据给可变数组赋值
先给出一个错误的写法:
1 2 3 4 5 /*-------------------------错误的赋值方法-------------------*/ NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; //这样写后,mutableArray 就变成了不可变数组了,如果你要在数组中添加或删除数据就会出现bug NSMutableArray *mutableArray = [user objectForKey:@"记住存放的一定是不可变的"];
正确的写法:
1 2 3 4 5 /*-------------------------正确的赋值方法-------------------*/ NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; //可以用alloc 方法代替 NSMutableArray *mutableArray = [NSMutableArray arrayWithArray:[user objectForKey:@"记住存放的一定是不可变的"]];
使用 NSUserDefaults 存储自定义对象
1、将自定义类型转换为NSData类型
当数据重复而且多的时候(例如想存储全班同学的学号,姓名,性别(这个数据量可能太大了 )),如果不用SQLite 存储 (多数据最好还是用这个),你可以选择使用归档,再将文件写入本地,但是这种方式和 NSUserDefaults 比起来麻烦多了(因为NSFileManage 本来就挺复杂) ,但是问题是,NSUserDefaults 本身不支持自定义对象的存储,不过它支持NSData的类型,下面举一个例子来介绍。
我们先建立一个叫Student 的类,这个类里有三个属性(学号,姓名,性别),如图:
![](http://images2015.cnblogs.com/blog/23250/201610/23250-20161003181834145-1260516689.png)
我们要做的就是将Student类型变成NSData类型 ,那么就必须实现归档:
这里要实现 在.h 文件中申明 NSCoding 协议,再 在 .m 中实现 encodeWithCoder 方法 和
initWithCoder 方法就可以了 :
.h 中修改文件如图 :
![](http://images2015.cnblogs.com/blog/23250/201610/23250-20161003181857239-402489604.jpg)
.m中加入代码 :
![](http://images2015.cnblogs.com/blog/23250/201610/23250-20161003181907192-668738465.png)
这样做就可以将自定义类型转变为NSData类型了
2、将自定义类型数据存入 NSUserDefaults 中
如果要存储全班同学的信息,我们可以建一个NSMutableArray 来存放全班同学的信息(里面存储的全是NSData对象)在需要存储的地方加入代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 //首先,要建立一个可变数组来存储 NSDate对象 Student* student = [[Student alloc] ini]; //下面进行的是对student对象的 name , studentNumber ,sex 的赋值 student.name = @"lady-奕奕"; student.studentNumber = @"3100104006"; student.sex = @"女"; //这是一个存放全班同学的数组 NSMutableArray* dataArray = [NSMutableArray arrayWithCapacity:50]; //将student类型变为NSData类型 NSData* data = [NSKeyedArchiver archivedDataWithRootObject:student]; //存放数据的数组将data加入进去 [dataArray addObject:data];
如果你只想存一个人的信息,你可以直接将NSData存入NSUserDefaults中 :
1 2 3 NSData *data = [NSKeyedArchiver archivedDataWithRootObject:student]; NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; [user setObject:data forKey:@"oneStudent"];
如果你想存储全班同学的信息,你还要用一个for循环将data 放入 dataArray中,这里具体的操作就不实现了,只给出存放的代码:
1 2 3 4 //记住要转换成不可变数组类型 NSArray * array = [NSArray arrayWithArray:dataArray]; NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; [user setObject:array forKey:@"allStudent"];
从NSUserDefaults中取出数据在还原也很简单。例如还原一个学生的数据:
1 2 3 4 5 NSUserDefaults *user = [NSUserDefaults standardUserDefaults]; NSdData *data = [user objectForKey:@"oneStudent"]; Student *student = [NSKeyedUnarchiver unarchiveObjectWithData:data];