1. 数组的持久化.
将数组中所有的元素的值存储到磁盘上的文件中.
plist: 属性列表文件.
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
文件的路径,文件后缀名写plist
属性列表文件的好处: 一目了然.
从plist文件中还原数组.
+ (nullable NSArray<ObjectType> *)arrayWithContentsOfFile:(NSString *)path;
NSDictionay
1. 先回顾一下NSArray和NSMutbaleArray.
是OC中的数组.
NSMutableArray数组的缺点:
NSMutableArray数组中的元素一旦删除.
这个元素后面的元素的下标会发生变化 会往前顶.
下标不靠谱. 要找到数组中特定的1个元素 不要使用下标去找,因为元素的下标可能会发生变化.
需求: 希望有一种靠谱的方式来快速定位数组中的元素.
每存储1个数据,都要求为这个数据取1个别名,
要找存储在数组中的数据的时候,不是通过下标来找,而是通过别名来找.
这样就算数组的元素的下标发生了变化. 不影响我们查找数据.因为我们不是通过下标来找数据 而是通过别名来找.
这中存储数据的方式我们叫做 键值对 的存储方式.
每存储1个数据(值) Value,都要为这个数据取1个别名(键).Key
NSDictionay 和 NSMutableDictionary 就是以键值对的形式来存储数据的.
2. NSDictionary数组.
1). 不可变字典数组.
2). 特点:
a. 首先是1个数组.
b. 是以键值对的形式来存储数据的
c. 存储的数据只能是OC对象.别名只能是遵守了NSCopying协议的OC对象. NSString就是遵守这个协议的.
d. 存储的键值对是固定的.不能动态的新增和删除.
3. 创建NSDictionary字典数组.
1). 这是1个类.要使用它的话,就必须要创建对象来使用.
NSDictionary *dict1 = [NSDictionary new];
NSDictionary *dict2 = [[NSDictionary alloc] init];
NSDictionary *dict3 = [NSDictionary dictionary];
这样的创建出来的字典数组,没有意义.这个时候这个字典数组的长度为0
而这个字典数组无法新增和删除元素.所以没有意义.
2). 常用的创建字典数组的方法
+ (instancetype)dictionaryWithObjectsAndKeys:(id)firstObject, ...
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:@"rose",@"name",@"18",@"age",@"178.5",@"height",nil];
依次的将值、键写在参数.最后1个写nil
3). 简要NSDictionary字典数组的方式.
NSDictionary *dict = @{键1:值1,键2:值2,键3:值3 ......};
NSDictionary *dict = @{
@"name":@"rose",
@"age":@"18",
@"height":@"178.6"
};
4. 如何取出存储在字典数组中的数据.
1). 字典数组中的数据不能使用下标去取.只能使用Key取Key对应的值.
2). 如何使用key取到这个key所对应的值.
a. 使用中括弧,在中括弧中写上别名,就可以取到这个别名对应的数据.
dict[别名];
b. 调用字典对象的方法.
- (nullable ObjectType)objectForKey:(KeyType)aKey;
如果给定的Key不存在,取到的就是nil.
5. 取到字典数组中键值对的个数.
@property (readonly) NSUInteger count;
6. 字典数组中的键是不能重复的. 因为键是用来区分字典数组中值的唯一标识.
如果键重复???????
7. NSDictionary字典数组的遍历.
1). 因为 NSDictionary字典数组中的取值是依靠键来取值的.无法通过下标来取值.
所以,for循环遍历下标的方式就不可以的啦...
2). 使用for in 循环.
注意的1点是: 遍历出来的数据是字典中的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;
}
}];
8. NSDictionary数组存储数据的原理.
1). 当我们往字典数组中存储键值对的.这个键值对不是挨个挨个的存储的.
2). 当我们要往这个字典数组中存储1个键值对的时候,
这个键值对要存储到哪1个下标中呢 ?
根据键做1个哈希算法和数组的长度 算出1个下标来.
然后把这个键值对存储到这个字典数组中对应下标处.
3). 我们取值是通过key取值的.
这个时候,仍然是根据这个Key做1个哈希算法.
算出这个key所在的下标 让后取值.
与NSArray的区别.
1). NSArray是1个1个的挨个存储.
NSDictionary不是挨个存储的.每1个键值对要存储在哪个下标处 都是通过算出来的.
所以,存储数据的时候,肯定是NSArray的效率高1些.
2). 取数据的时候.
如果我们要讲数组中的所有的元素取出来.
取的时候,肯定是NSArray快.
NSArray挨个挨个的取就可以 而字典每取1个就要算1下.
3). 使用场景.
如果我们往数组中存储数据,存储进去以后,凡是要取数据都是全部取出来.使用NSArray.
` 如果取值的时候,只会取其中的特定的几个.使用字典数组.
-------------------------------
1. NSMutableDictionary.可变字典数组.
1). 是NSDictionary的子类. 所以它也是以键值对的形式来存储数据.
和父类的不同之处: 键值对可以动态的新增和删除.
2. 创建可变字典数组.
NSMutableDictionary *dict1 = [NSMutableDictionary new];
NSMutableDictionary *dict2 = [[NSMutableDictionary alloc] init];
NSMutableDictionary *dict3 = [NSMutableDictionary dictionary];
上面的这些方法创建出来的可变字典的长度是0 这是有意义的.因为可以动态的新增和删除.
NSMutableDictionary *dict4 = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"jack",@"name",@"17",@"age",nil];
注意:
NSMutableDictionary *dict3 = @{}; 这么做是不行的.
3. 如何新增键值对.
- (void)setObject:(ObjectType)anObject forKey:(KeyType <NSCopying>)aKey;
值可以是任意的OC对象.
键必须是遵守了NSCopying协议的对象. NSString就是遵守了这个协议.
如果键重复,后新增会将前面的值覆盖掉.
值是可以重复的
4. 删除键值对.
[dict removeAllObjects];//全部清空.
[dict removeObjectForKey:@"name"];//删除这个键对应的键值对.
5. 字典数组也可以持久化为1个plist文件.
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile;
//将pist文件还原为1个字典 返回值的类型NSDictionary
//但是实际的对象,是1个可变的.
+ (nullable NSDictionary<KeyType, ObjectType> *)dictionaryWithContentsOfFile:(NSString *)path;
1. 集合的内存管理.
集合: OC中的数组 NSArray 和 NSDictionary统称为集合.
2. 在MRC的模式下.
将1个对象存储到集合中.
会为这个对象的引用计数器+1.
当集合被销毁的时候,那么就会为存储在集合中的对象发送1条release消息.
3. 在ARC模式下:
集合的元素的类型是个强类型的指针.
在ARC的模式下,使用类方法创建的对象收不了. ???????????
4. 以@[] @{} 创建的集合,已经是被autorelease过的了.
1). MRC模式下: 将1个对象存储到集合中,会为这个对象的引用计数器+1
这个集合释放,会为这个集合中的对象发送1条release消息.
2). 在ARC的模式下: 集合的元素是强类型的指针.
1. NSFileManger是Foundation框架提供的1个类.
这个类作用: 用来操作磁盘上的文件 文件夹 对他们进行创建、删除、复制 拷贝 移动.....
2. NSFileManager是1个类.
这个类的对象是以单例模式创建的.
如何得到NSFileManager的1个单例对象.
掉用这个类的类方法,defaultManager 就可以得到这个类的单例对象
NSFileManager *fileManager = [NSFileManager defaultManager];
3. 常用方法之 判断.
1). 判断指定的文件或者文件夹在磁盘上是否真实的存在
- (BOOL)fileExistsAtPath:(NSString *)path;
2).判断指定的路径是否真实的存储在我们的磁盘之上,并且判断这个路径是1个文件夹路径还是1个文件路径.
- (BOOL)fileExistsAtPath:(NSString *)path isDirectory:(BOOL *)isDirectory;
返回值:代表这个路径是否真实存在.
参数指针: 代表这个路径是否是1个文件夹路径
3). 判断指定的文件夹或者文件是否可以读取.
- (BOOL)isReadableFileAtPath:(NSString *)path;
4). 判断指定的文件夹或者文件是否可以写入.
- (BOOL)isWritableFileAtPath:(NSString *)path;
5). 判断指定的文件夹或者文件是否可以删除.
- (BOOL)isDeletableFileAtPath:(NSString *)path
4. 常见方法之 获取信息.
1).获取指定文件或者文件夹的属性信息.
- (NSDictionary *)attributesOfItemAtPath:(NSString *)path error:(NSError **)error
返回的是1个字典,如果要拿到特定的信息 通过key
2).获取指定目录下的所有的文件和目录. 是拿到指定目录下的所有的文件和目录 所有的后代目录和文件.
子目录的子目录的子目录 所有的都可以拿到.
- (NSArray *)subpathsAtPath:(NSString *)path;
3).获取指定目录下的所有的子目录和文件 不保护孙子辈.
- (NSArray *)contentsOfDirectoryAtPath:(NSString *)path error:(NSError **)error
5. 常见方法之 文件/目录的创建
1). 在指定的目录创建文件.
- (BOOL)createFileAtPath:(NSString *)path contents:(NSData *)data attributes:(NSDictionary *)attr
第1个参数: 要创建的文件的路径.
第2个参数: 这个文件的内容. 要传递这个文件的二进制格式.
这个二进制的数据格式 使用NSData对象来封装.
NSData: 将别的格式的数据转换为二进制数据.
将字符串转换为NSData二进制的方式.调用字符串对象的
- (NSData *)dataUsingEncoding:(NSStringEncoding)encoding
编码参数: NSUTF8StringEncoding
指定1个编码 就可以将字符串转换为二进制数据 存储在NSData对象之中.
最后再将这个二进制对象通过这个方法写入.
如果想创建1个空文件 第2个参数就给nil
第3个参数: 指定创建的文件的属性.如果想要使用系统的默认值使用nil
2). 在指定的目录创建文件夹.
- (BOOL)createDirectoryAtPath:(NSString *)path withIntermediateDirectories:(BOOL)createIntermediates attributes:(NSDictionary *)attributes error:(NSError **)error
第1个参数: 路径.
第2个参数: YES,做一路创建. 如果是NO就不会做一路创建.
第3个参数: 指定属性 nil为系统默认属性.
第4个参数.
3).拷贝文件.
- (BOOL)copyItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error
4).移动文件 剪切 文件的重命名. 重名的原理: 将文件移动到原来的目录并改名.
- (BOOL)moveItemAtPath:(NSString *)srcPath toPath:(NSString *)dstPath error:(NSError **)error
5).删除文件.
- (BOOL)removeItemAtPath:(NSString *)path error:(NSError **)error
注意 删除的文件不会倒废纸篓 而是直接删除,所以请小心使用.
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) | 黑马程序员IT技术论坛 X3.2 |