您的位置:首页 > 其它

字典转模型

2016-11-09 21:42 176 查看

用模型取代字典的好处

什么是模型

专门用来存放数据的对象

一般都是一些直接继承自
NSObject
的纯对象

内部会提供一些属性来存放数据

使用字典的弊端

一般情况下,设置数据和取出数据都使用“字符串类型的key”,编写这些key时,编辑器没有智能提示,需要手敲

dict[@"name"] = @"Jack"; // 赋值
NSString *name = dict["@name"]; // 取值


手敲字符串key时容易写错

key如果写错了,编译器不会有任何警告和报错,造成设错数据或取错数据。

使用模型的好处

所谓模型,其实就是数据模型,专门用来存放数据对象,用它来标识数据会更加专业

模型设置数据和取出数据都是通过它的属性,属性名如果写错了,编译器会马上报错,由此保证了数据的正确性

使用模型访问属性时,编译器会提供一系列的提示,提高编码效率

app.name = @"Jack"; // 赋值
NSString *name = app.name; // 取值

字典转模型

首先创建一个模型

这里创建一个名叫
WXDShops
的模型

在模型的.h文件中声明两个属性

/** 商品名称  */
@property(nonatomic,strong) NSString *name;
/** 图标*/
@property(nonatomic,strong) NSString *icon;

在viewController.m文件中使用

先import进来

修改前代码:

NSDictionary *dict = _shops[index];
img.image = [UIImage imageNamed:dict[@"icon"]];
wLabel.text = dict[@"name"];


修改后代码:

NSDictionary *dict = _shops[index];
WXDShops *shop = [[WXDShops alloc] init];
shop.name = dict[@"name"];
shop.icon = dict[@"icon"];
img.image = [UIImage imageNamed:shop.icon];
wLabel.text = shop.name;

这样看代码似乎变多了,但是会一劳永逸,以后再用,直接用“shop.***”就出来了。

代码优化

以上代码都是写在控制器中的,但是控制器“知道的太多,会死的很惨”!

只要模型里面的数据发生了改变,控制器里所有字典转模型的代码都要改

只要字典里的key值有改动,控制器里的字典转模型的也要改

模型不一定是用在一个控制器里,多个控制器用到模型,一旦改动,所有的都要改

因此以上字典转模型的过程最好封装在模型内部

并且模型应该提供一个可以传入字典的构造方法

提供一个
initWithDict
的构造方法,在初始化的时候就将数据赋给模型

-(id)initWithDict:(NSDictionary *)dict {
if (self = [super init]) {
self.name = dict[@"name"];
self.icon = dict[@"icon"];
}
return self;
}


同时提供一个以类名开头的类方法

+(id)shopWithDict:(NSDictionary *)dict {
return [[self alloc] initWithDict:dict];
}

以类名开头来命名是遵循了苹果官方的原则

这时上面的代码可以优化为:

NSDictionary *dict = _shops[index];
WXDShops *shop = [[WXDShops alloc] initWithDict:dict];
//WXDShops *shop = [WXDShop shopWithDict:dict];
img.image = [UIImage imageNamed:shop.icon];
wLabel.text = shop.name;


想要让字典转模型的代码也是只加载一次,因此将字典转模型代码放在懒加载中

-(NSArray *)shops {
if (_shops == nil) {
//加载一个字典数组
NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"shops" ofType:@"plist"]];

NSMutableArray *shopArray = [NSMutableArray array];
for (NSDictionary *dict in dictArray) {
WXDShops *shop = [WXDShops shopWithDict:dict];
[shopArray addObject:shop];
}
_shops = shopArray;
}
return _shops;
}


这样,前面优化的代码前两行可更改为一行:

WXDShops *shop = self.shops[index];

这样,在加载数据的那一刻,转模型已经转完了,且只加载了一次

instancetype

instancetype在类型表示上,跟id一样,可以表示任何对象类型

instancetype只能用在返回值类型上,不能像id一样用在参数类型上

instancetype比id多一个好处:编译器会检测instancetype的真实类型

因此以后的id返回类型都写成instancetype类型

类前缀

使用Objective-C开发iOS程序时,最好在每个类前面加一个前缀

目的是防止N个人开发了一样的类,冲突了

比如JakeWill、KateRoom在同一个项目中都开发了Button类,这样的程序是不能运行起来的

解决方案:JakeWill的类名叫JWButton,KateRoom的类名叫KRButton

但是每次新建类的时候,都手写前缀很麻烦,能不能让前缀可以自动生成呢?看下图



作者:黎明豌豆

出处:http://www.cnblogs.com/PeaZora/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此字段声明,且在文章页面明显位置给出原文链接,否则保留追究法律责任的权利
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: