零基础iOS开发学习日记-功能篇-读取plist和数组转模型

911 阅读3分钟

开头

读取plist和数组转模型

实际用处

  • 存储少键的数据

数据形式

  • 最外面一层一般是数组,往内一层为字典
  • 数组中的每个元素,内容都是一样的

读取思路

  • 数组转模型
  • 把最外一层数组中的每个元素看作一个对象,将数组中的键看作对象的属性

基本解析操作

  • 下面的以存放省市的plist为例,结构为plist文件包含citys省的名字,如数组第一项中包含

3.png

  1. 读取plist
NSString *path = [[NSBundle mainBundle] pathForResource:@"cities.plist" ofType:nil];
NSArray *arr = [NSArray arrayWithContentsOfFile:path];
  1. 创建对象,对象中的属性与数组中的键名一致
.h 中
@property (nonatomic, strong) NSArray *cities;
@property (nonatomic, copy) NSString *name;

- (instancetype)initWithDict:(NSDictionary *)dict;
+ (instancetype)pronvinceWithDict:(NSDictionary *)dict;
.m 中
- (instancetype)initWithDict:(NSDictionary *)dict
{
    if (self = [super init]) {
        [self setValuesForKeysWithDictionary:dict];
    }
    return self;
}
+(instancetype)pronvinceWithDict:(NSDictionary *)dict
{
    return  [[self alloc] initWithDict:dict];
}
  1. 解析数组,数组转模型,而这里在创建可变数组的时候,要提前给一个容量,提高运行效率
NSMutableArray *provinces = [NSMutableArray arrayWithCapacity:20];
for (NSDictionary *dict in arr) {
    Province *province = [Province pronvinceWithDict:dict];
    [provinces addObject:province];
}

数组转模型关键函数

  • [self setValuesForKeysWithDictionary:dict]; 这个函数是数组转模型的关键,会将字典中的键赋给对象中的同名属性,本质如下
self.name = dict[@"name"];
self.cities = dict[@"cities"];

错误处理

  • plist中有相应的键,对象中没有相应的属性。重写下面这个函数即可
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
    
}

两层数组转模型

  • 下面的例子以QQ好友为例子,QQ好友列表有多个分组,而每个分组又有多个好友,每个好友又有姓名、个性签名等相同的属性,如下
  • 分组列表 image.png
  • 好友列表 image.png
  • 分析之后,就可以把每一个分组看作一个对象,再进而把一个好友看作一个对象,而好友对象有作为分组对象的一个属性
  • 这里对于好友对象数组转模型处理跟上面一样,但是对于分组对象中的数组转模型,要特殊处理。在分组对象的数据处理中,要进行好友对象的数组转模型
- (instancetype)initWithDict:(NSDictionary *)dict
{
    if (self = [super init]) {
        [self setValuesForKeysWithDictionary:dict];
        //数据里嵌套数组
        //把self.friends由字典数组转换为模型数据
        NSMutableArray *arrayModels = [NSMutableArray new];
        for (NSDictionary *dict_sub in self.friends) {
            Friend *friend = [Friend friendWithDict:dict_sub];
            [arrayModels addObject:friend];
        }
        self.friends = arrayModels;
    }
    return self;
}
+(instancetype)groupWithDict:(NSDictionary *)dict
{
    return  [[self alloc] initWithDict:dict];
}

输出测试

  • 在实际开发中,再写好模型数组后,往往需要测试模型中的数组是否被成功复制,而系统的输出又太麻烦,这就需要重写类的description函数,进行自定义输出
  • 以上面的plist为例
- (NSString *)description
{
    NSMutableString *strM = [NSMutableString new];
    [self.friends enumerateObjectsUsingBlock:^(Friend * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [strM appendFormat:@"%@\n", obj.name];
    }];
    return [NSString stringWithFormat:@"%@\n%p\n%@\n%@",
            [self class], //类名
            self, //类指针地址
            self.name, //模型属性,这里是分组名
            strM]; //输出下一层模型的属性,OC无法直接输出数组中的内容,这里是好友的名字
}

总结

  1. 适用于少键的数据处理,并且可以保存在app沙盒目录下
  2. 要注意模型属性与文件中的键的对应
  3. 要注意及时测试,和不需要的键的处理
  4. 在实际开发中,可以利用plist文件,进行界面多态的实现,例如,设置栏界面,样式基本相同,但是里面的内容不同