plist 文件
*直接将数据直接写在代码里面,不是一种合理的做法。如果数据经常改,就要经常翻开对应的代码进行修改,造成代码扩展性低
*因此,可以考虑将经常变的数据放在文件中进行存储,程序启动后从文件中读取最新的数据。如果要变动数据,直接修改数据文件即可,不用修改代码
*一般可以使用属性列表文件存储NSArray或者NSDictionary之类的数据,这种“属性列表文件”的扩展名是plist,因此也称为“plist文件”
解析Plist问题
接下来通过代码来解析Plist文件中的数据
// 获得Plist文件的全路径 NSBundle *bundle = [NSBundle mainBundle]; NSString *path = [bundle pathForResource:@"****" ofType:@"plist"]; // 加载plist文件 _shops = [NSArray arrayWithContentsOfFile:path];
plist 注意问题:
plist 的文件名不能使用”info“”Info“之类的
添加plist等文件资源的时候,一定要勾选下面的选项 Add to targets (第一个选项)
用模型取代字典的好处
l使用字典的坏处
Ø一般情况下,设置数据和取出数据都使用“字符串类型的key”,编写这些key时,编辑器没有智能提示,需要手敲
dict[@"name"] = @"Jack";
NSString *name = dict[@"name"];
Ø手敲字符串key,key容易写错
ØKey如果写错了,编译器不会有任何警告和报错,造成设错数据或者取错数据
l使用模型的好处
Ø所谓模型,其实就是数据模型,专门用来存放数据的对象,用它来表示数据会更加专业
Ø模型设置数据和取出数据都是通过它的属性,属性名如果写错了,编译器会马上报错,因此,保证了数据的正确性
Ø使用模型访问属性时,编译器会提供一系列的提示,提高编码效率
app.name = @"Jack";
NSString *name = app.name;
字典转模型
*字典转模型的过程最好封装在模型内部
*模型应该提供一个可以传入字典参数的构造方法
- (instancetype)initWithDict:(NSDictionary *)dict; + (instancetype)xxxWithDict:(NSDictionary *)dict;
instancetype 与 id 的区别
*instancetype在类型表示上,跟id一样,可以表示任何对象类型
*instancetype只能用在返回值类型上,不能像id一样用在参数类型上
*instancetype比id多一个好处:编译器会检测instancetype的真实类型
类前缀:
*使用Objective-C开发iOS程序时,最好在每个类名前面加一个前缀,用来标识这个类的“老家”在哪
目的是防止N个人开发了一样的类,冲突了
*比如Jake Will、Kate Room在同一个项目中都各自开发了个Button类,这样的程序是不能运行起来的
*解决方案:Jake Will的类名叫做JWButton,Kate Room的类名叫做KRButton
1.plist存储,生成一个plist文件.
2.plist不是数组就是字典,plist存储就是用来存储字典或者数组.
`注意:Plist不能存储自定义对象`
3.获取应用沙盒中Caches文件路径
// directory:获取哪个文件夹 // domainMask:在哪个范围内搜索,NSUserDomainMask:表示在用户的手机上查找 // expandTilde:是否展开全路径 YES:表示展开全路径 NO:不会展开全路径,会把应用沙盒的路径用波浪号(~)代替 // 获取到Caches文件夹路径 NSString *cachePath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES)[0];
4.读取plist,之前是什么类型存储的,读取也是什么
## 2.偏好设置存储
// 偏好设置存储:NSUserDefaults
// 以字典的形式进行偏好设置,用法跟字典.
// 偏好设置好处: 1.不需要关心文件名
// 2.快速进行键值对存储
// 3.直接存储基本数据类型
## 3.归档
1.NSKeyedArchiver专门用来做自定义对象归档
// 什么时候调用:当一个对象要归档的时候就会调用这个方法归档 // 作用:告诉苹果当前对象中哪些属性需要归档 - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:_name forKey:@"name"]; [aCoder encodeInt:_age forKey:@"age"]; } // 什么时候调用:当一个对象要解档的时候就会调用这个方法解档 // 作用:告诉苹果当前对象中哪些属性需要解档 // initWithCoder什么时候调用:只要解析一个文件的时候就会调用 - (id)initWithCoder:(NSCoder *)aDecoder { #warning [super initWithCoder] if (self = [super init]) { // 解档 // 注意一定要记得给成员属性赋值 _name = [aDecoder decodeObjectForKey:@"name"]; _age = [aDecoder decodeIntForKey:@"age"]; } return self; }