OC中的集合包含哪些?
包括NSArray、NSDictionary 和它们对应的子类 NSMutableArray、NSMutableDictionary.
数组的持久化
将数组中所有的元素的值存储到磁盘上的文件中.
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
从plist文件中还原数组.
+(nullable NSArray *)arrayWithContentsOfFile:(NSString *)path;
NSDictionary存在的理由?
NSArray和NSMutableArray是OC中的数组
它们存储数据的特点是每一个元素都是紧密相连的,通过下标获取存储的值.
它们的缺点是数组元素的下标不固定,增加、删除、插入等等操作后,数组元素的下标会相应发生改变.
所以我们希望有一种存储方式,存储到数组中,可以快速唯一的确定数据的元素.
所以字典数组(NSDictionary、NSMutableDictionary)这种键值对(key - value)的存储方式就出现了
key - value
key 就是键, 就是为数据取的别名,键只能是遵守了NSCoping协议的对象,而NSString就是遵守了这个协议,所以字符串对象可以作为key值.
value 就是值,就是真正存储的数据,只能是OC对象.
常用的创建字典数组的方法
+(instancetype)dictionaryWithObjectsAndKeys:(id)firstObject,...
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"rose",@"name",@"18",@"age",@"178.5",@"height",nil];
依次的将值、键写在参数,最后1个写nil.
简要NSDictionary字典数组的方法
NSDictionary *dict = @{键1:值1,键2:值2,键3:值3 ......};
NSDictionary *dict = @{
@"name":@"rose",
@"age":@"18",
@"height":@"178.6"
};
如何取出存储在字典数组中的数据?
1). 字典数组中的数据不能使用下标去取.只能使用key取key对应的值.
2). 如何使用key取到这个key所对应的值.
a. 使用中括弧,在中括弧中写上别名,就可以取到这个别名对应的数据.
dict[别名];
b.调用字典对象的方法.
-(nullable ObjectType)objectForKey:(KeyType)aKey;
如果给定的Key不存在,取到的就是nil.
ps:字典数组中的键是不能重复的,因为键是用来区分字典数组中值的唯一标识.
如何取到字典数组中键值对的个数?
@property(readonly)NSUInteger count;
NSDictionary字典数组的遍历
1). 因为NSDictionary字典数组中的取值是依靠键来取值的,所以无法通过下标来取值.
2).使用for in循环.
注意的一点是: 遍历出来的数据是字典中的key,要取值的话,还要通过key去取值.
for(NSString *key in dict){
NSLog(@"%@ = %@",key,[dict objectForKey:key]);
}
3). 使用block来遍历字典数组.
-(void)enumerateKeysAndObjectsUsingBlock:(void(^)(KeyType key,ObjectType obj,BOOL *stop))block;
[dict enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key,id _Nonnull obj,BOOL * _Nonnull stop){
//key遍历出来的键.
//obj遍历出来的值.
//stop指针.
NSLog(@"%@ = %@",key,obj);
if([key isEqualToString:@"age"]){
*stop = YES;
}
}];
NSDictionary数组存储数据的原理
当我们往字典数组中存储键值对的时候,这个键值对不是挨个挨个的存储的,而是根据键值做一个哈希算法算出一个下标,然后把这个键值对存储到这个字典数组中对应下标处.
我们取值是通过key取值的,这个时候仍然是根据这个key值做一个哈希算法算出这个key所在的下标,然后取值.
NSArray和NSDictionary分别的使用场景?
如果我们往数组中存储数据,存储进去以后,凡是要取数据都是全部取出来.使用NSArray.如果取值的时候,只会取其中的特定的几个,就使用NSDictionary数组.
可变字典数组(NSMutableDictionary)
是NSDictionary的子类,所以它也是以键值对的形式来存储数据,和父类的不同之处是它的键值对可以动态的新增和删除.
创建可变字典数组
NSMutableDictionary *dict1 = [NSMutableDictionary new];
NSMutableDictionary *dict2 = [[NSMutableDictionary alloc] init];
NSMutableDictionary *dict3 = [NSMutableDictionary dictionary];
上面的这些方法创建出来的可变字典的长度是0,这是有意义的.因为NSMutableDictionary对象可以动态的新增和删除键值对.
最常使用创建NSMutableDictionary对象的方法
NSMutableDictionary *dict4 = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"jack",@"name",@"17",@"age",nil];
ps: NSMutableDictionary *dict5 = @{}, 这么创建是不行的.
新增键值对
-(void)setObject:(ObjectType)anObject forKey:(KeyType )aKey;
值可以是任意的OC对象,键必须是遵守了NSCopying协议的对象,NSString就是遵守了这个协议.
如果键重复,后新增会将前面的值覆盖掉,值是可以重复的.
删除键值对
[dict removeAllObjects];//全部清空
[dict removeObjectForKey:@"name"];//删除这个键对应的键值对.
字典数组也可以持久化为1个plist文件
-(BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
//根据路径拿到字典数组
+(nullable NSDictionary *)dictionaryWithContentsOfFile:(NSString *)path;
集合的内存管理
在MRC中将对象存储到集合之中,会为这个对象的引用计数器+1,当集合销毁的时候,就会向存储在集合中的所有对象发送一条release消息.
使用@[] 或者@{ }创建的集合已经被autorelease过了,直接调用和类同名的类方法创建的对象也是被autorelease过的.
在ARC的模式下,集合的元素是一个强类型的指针.