字典转模型
0> 字典转模型的含义: 把字典中的数据使用模型来保存。新建一个类, 根据字典中键值对的个数, 来编写这个类中的属性, 将来用这个类的对象的属性来保存字典中每个键对应的值。
1> 为什么要把字典转成模型?
* 字典缺陷:
0> 写代码的时候字典的键没有智能提示, 但是模型的属性可以有智能提示
1> "键"是字符串, 如果写错了, 编译器不报错(在编译的时候不报错), 运行时可能出错, 出错了很难找错。
2> 使用"模型"可以更方便的使用面向对象的3大特(封装、继承、多态)性进行扩展。
* 什么是模型? "模型"就是自定义的类, 通过为"类"增加各种属性来保存数据。
* 字典转模型要修改哪里的代码?
1> 创建一个模型类
2> 在懒加载数据的时候, 把加载到的数据都放到模型对象中, 然后再把模型对象放到数组中。
代码如下:
app.plist文件
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<dict>
<key>name</key>
<string>天天酷跑</string>
<key>icon</key>
<string>icon_00</string>
</dict>
<dict>
<key>name</key>
<string>全民飞机大战</string>
<key>icon</key>
<string>icon_01</string>
</dict>
<dict>
<key>name</key>
<string>Flappy Bird</string>
<key>icon</key>
<string>icon_02</string>
</dict>
<dict>
<key>name</key>
<string>天天飞车</string>
<key>icon</key>
<string>icon_03</string>
</dict>
<dict>
<key>name</key>
<string>节奏大师</string>
<key>icon</key>
<string>icon_04</string>
</dict>
<dict>
<key>name</key>
<string>爸爸去哪儿</string>
<key>icon</key>
<string>icon_05</string>
</dict>
<dict>
<key>name</key>
<string>欢乐斗地主</string>
<key>icon</key>
<string>icon_06</string>
</dict>
<dict>
<key>name</key>
<string>天天爱消除</string>
<key>icon</key>
<string>icon_07</string>
</dict>
<dict>
<key>name</key>
<string>神庙逃亡2</string>
<key>icon</key>
<string>icon_08</string>
</dict>
<dict>
<key>name</key>
<string>欢乐麻将</string>
<key>icon</key>
<string>icon_09</string>
</dict>
<dict>
<key>name</key>
<string>保卫萝卜2</string>
<key>icon</key>
<string>icon_10</string>
</dict>
<dict>
<key>name</key>
<string>神偷奶爸</string>
<key>icon</key>
<string>icon_11</string>
</dict>
</array>
</plist>
模型文件:
CZApp.h如下:
#import <Foundation/Foundation.h>
@interface CZApp : NSObject
@property(nonatomic,copy) NSString *name; //最好和字典字段一样,便于维护
@property(nonatomic,copy) NSString *icon;
-(instancetype)initWithDict:(NSDictionary *)dict; //对象方法
+(instancetype)appWithDict:(NSDictionary *)dict; //封装 类方法
@end
CZApp.m文件如下:
#import "CZApp.h"
@implementation CZApp
-(instancetype)initWithDict:(NSDictionary *)dict
{
if(self=[super init])
{
self.name=dict[@"name"];
self.icon=dict[@"icon"];
}
return self;
}
+(instancetype)appWithDict:(NSDictionary *)dict
{
return [[self alloc]initWithDict:dict];
}
@end
ViewController.m文件(进行使用)
@interface ViewController ()
@property(nonatomic,strong) NSArray *apps;
@end
@implementation ViewController
//重写get方法,懒加载数据
-(NSArray *)apps{
if (_apps==nil) {
{
//获取app.plist文件在手机上的路径
NSString *path=[[NSBundle mainBundle]pathForResource:@"app.plist" ofType:nil];
//2.根据路径加载数据
NSArray *arrDict=[NSArray arrayWithContentsOfFile:path];
// 3. 创建一个可变数组对象用来保存一个一个的模型对象
NSMutableArray *arrayModels=[NSMutableArray array];
// 4. 循环字典数组, 把每个字典对象转换成一个模型对象
for (NSDictionary *dict in arrDict) {
CZApp *model=[CZApp appWithDict:dict];
[arrayModels addObject:model];
}
_apps=arrayModels;
}
}
return _apps;
}<pre name="code" class="objc">@end
*懒加载数据:就是重写数据字段的get方法
* 把字典转模型的过程封装到"模型"内部
* 原因: 将来的这个"模型"可能会在很多地方被用到(比如有很多个控制器都会使用这个模型), 那么每次用到模型的地方都需要写一次把字典中的数据赋给模型属性的代码, 此时如果把这些赋值语句封装到模型内部, 会大大简化了使用复杂度与代码量。
* 思路:
1> 在模型中接受一个NSDictionary的参数, 然后在模型内部把NSDictioanry中的数据赋值给模型的属性。
2> 封装一个initWithDict方法和一个appWithDict方法
* id与instancetype的介绍
1. 使用id作为方法返回值的问题:
1> 在接收方法的返回值的时候可以使用任何类型来接收, 编译都不报错, 但是运行时可能出错。
2. instancetype需要注意的点
1> instancetype在类型表示上, 与id意思一样, 都表示任何对象类型
2> instancetype只能用作返回值类型, 不能向id一样声明变量、用作参数等
3> 使用instancetype, 编译器会检测instancetype的真实类型, 如果类型不匹配, 编译时就报错了。(instancetype出现在哪个类型中就表示对应的类型)