用模型取代字典
使用字典的坏处
一般情况下,设置数据和取出数据都使用“字符串类型的key”,编写这些key时,编辑器没有智能提示,需要手敲
dict[@"name"] = @"Jack";NSString *name = dict[@"name"];
- 手敲字符串key,key容易写错
- Key如果写错了,编译器不会有任何警告和报错,造成设错数据或者取错数据
使用模型的好处
- 所谓模型,其实就是数据模型,专门用来存放数据的对象,用它来表示数据会更加专业
- 模型设置数据和取出数据都是通过它的属性,属性名如果写错了,编译器会马上报错,因此,保证了数据的正确性
- 使用模型访问属性时,编译器会提供一系列的提示,提高编码效率
app.name = @"Jack";NSString *name = app.name;
字典转模型
1.字典转模型的过程最好封装在模型内部
2.模型应该提供一个可以传入字典参数的构造方法
- (instancetype)initWithDict:(NSDictionary *)dict;+ (instancetype)xxxWithDict:(NSDictionary *)dict;
instancetype与id区别
id:代指所有类型,但是使用不恰当的类型指针指向不匹配的对象时,编译器不会报错、警告,但在运行时很可能会出错 instantcetype:
- instancetype在类型表示上,跟id一样,可以表示任何对象类型
- instancetype只能用在返回值类型上,不能像id一样用在参数类型上
- instancetype比id多一个好处:编译器会检测instancetype的真实类型
编码实现
UYAppInfo.h
//// UYAppInfo.h// 4.0应用程序管理#import@interface UYAppInfo : UITabBar@property (nonatomic, copy) NSString *name;@property (nonatomic, copy) NSString *icon;/** 通常在写模型的实例化方法时,以下两个方法,都需要实现 *//** 使用字典实例化模型 */- (instancetype)initWithDict:(NSDictionary *)dict;/** 类方法可以快速实例化一个对象 */+ (instancetype)appInfoWithDict:(NSDictionary *)dict;/** 返回所有plist中的数据模型数组 */+ (NSArray *)appList;@end
UYAppInfo.m
//// UYAppInfo.m// 4.0应用程序管理//// Created by jiangys on 15/8/23.// Copyright (c) 2015年 uxiaoyuan. All rights reserved.//#import "UYAppInfo.h"@implementation UYAppInfo- (instancetype)initWithDict:(NSDictionary *)dict{ // self 是 对象 self = [super init]; if (self) { // 方法一: // 用字典给属性赋值,所有与plist键值有关的方法,均在此处! // self.name = dict[@"name"]; // self.icon = dict[@"icon"]; // 方法二: // KVC - key value coding键值编码 // 是一种间接修改/读取对象属性的一种方法 // KVC 被称为 cocoa 的大招! // 参数: // 1. 数值 // 2. 属性名称 // [self setValue:dict[@"name"] forKeyPath:@"name"]; // [self setValue:dict[@"icon"] forKeyPath:@"icon"]; // setValuesForKeysWithDictionary本质上就是调用以上两句代码 [self setValuesForKeysWithDictionary:dict]; } return self;}+ (instancetype)appInfoWithDict:(NSDictionary *)dict{ // self 是 class return [[self alloc] initWithDict:dict];}+ (NSArray *)appList{ NSArray *array = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil]]; // 创建一个临时数组 NSMutableArray *arrayM = [NSMutableArray array]; // 遍历数组,依次转换模型 for (NSDictionary *dict in array) { [arrayM addObject:[UYAppInfo appInfoWithDict:dict]]; } return arrayM;}@end
实际上,这部分的格式更像:
// 对象方法- (instancetype) initWith数据源名:(NSDictionary *) 数据源 { if (self = [super init]) { self.属性 = 数据源[KEY名]; } return self;}// 类方法+ (instancetype) 类名With数据源名:(NSDictionary *) 数据源 { return [[self alloc] initWith数据源名:数据源];}
最后的实现就很简单了
UYViewController.m
-(NSArray *) appList{ if (nil==_appList) { //NSString *path=[[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil]; //_appList=[NSArray arrayWithContentsOfFile:path]; _appList=[UYAppInfo appList]; } return _appList;}
获取一个对象:
UYAppInfo *appData=self.appList[i];
使用model:
lable.text = appData.name;