1.使用字典的坏处
一般情况下,设置数据和取出数据都使用“字符串类型的key”,编写这些key时,编译器不会有任何友善提示,需要手敲dict[@"name"] = @"Jack";
NSString *name = dict[@"name"];
手敲字符串key,key容易写错
Key如果写错了,编译器不会有任何警告和报错,造成设错数据或者取错数据
使用模型的好处
所谓模型,其实就是数据模型,专门用来存放数据的对象,用它来表示数据会更加专业
模型设置数据和取出数据都是通过它的属性,属性名如果写错了,编译器会马上报错,因此,保证了数据的正确性
使用模型访问属性时,编译器会提供一系列的提示,提高编码效率
app.name = @"Jack”;
NSString *name = app.name;
2.使用模型实现如下程序
3.实现步骤
1.plist文件
2.字典转模型的过程
模型应该提供一个可以传入字典参数的构造方法
- (instancetype)initWithDict:(NSDictionary *)dict;
+ (instancetype)xxxWithDict:(NSDictionary *)dict;
3.代码:
3.1模型类:
// MJApp.h
// 模型类:用来存放数据的类
#import <Foundation/Foundation.h>
/**
copy : NSString
strong: 一般对象
weak: UI控件
assign:基本数据类型
*/
//因为app.plist的每个元素都是一个字典 具有name和icon属性(详见app.plist)
@interface MJApp : NSObject
/**
* 名称
*/
@property (nonatomic, copy) NSString *name;
/**
* 图标
*/
@property (nonatomic, copy) NSString *icon;
/**
* 通过字典来初始化模型对象
*
* @param dict 字典对象
*
* @return 已经初始化完毕的模型对象
*/
- (instancetype)initWithDict:(NSDictionary *)dict;
+ (instancetype)appWithDict:(NSDictionary *)dict;
@end
// MJApp.m
#import "MJApp.h"
@implementation MJApp
- (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
3.2控制器类
// MJViewController.m
#import "MJViewController.h"
#import "MJApp.h"
@interface MJViewController ()
/** 存放应用信息 */
@property (nonatomic, strong) NSArray *apps;
@end
@implementation MJViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// 添加应用信息
// 0.总列数(一行最多3列)
int totalColumns = 3;
// 1.应用的尺寸
CGFloat appW = 85;
CGFloat appH = 90;
// 2.间隙 = (控制器view的宽度 - 3 * 应用宽度) / 4
CGFloat marginX = (self.view.frame.size.width - totalColumns * appW) / (totalColumns + 1);
CGFloat marginY = 15;
// 3.根据应用个数创建对应的框框(index 0 ~ 11)
for (int index = 0; index<self.apps.count; index++) {
// 3.1.创建1小框框
UIView *appView = [[UIView alloc] init];
// 设置背景色
// appView.backgroundColor = [UIColor redColor];
// 3.2.计算框框的位置
// 计算行号和列号
int row = index / totalColumns;
int col = index % totalColumns;
// 计算x和y
CGFloat appX = marginX + col * (appW + marginX);
CGFloat appY = 30 + row * (appH + marginY);
// 设置frame
appView.frame = CGRectMake(appX, appY, appW, appH);
// 3.3.添加框框到控制器的view
[self.view addSubview:appView];
// 3.4.添加内部的小控件
// 3.4.0.index位置对应的应用信息
MJApp *appInfo = self.apps[index];
// 3.4.1.添加图片
UIImageView *iconView = [[UIImageView alloc] init];
// 设置位置
CGFloat iconW = 45;
CGFloat iconH = 45;
CGFloat iconX = (appW - iconW) * 0.5;
CGFloat iconY = 0;
iconView.frame = CGRectMake(iconX, iconY, iconW, iconH);
// 设置图片
iconView.image = [UIImage imageNamed:appInfo.icon];
[appView addSubview:iconView];
// 3.4.2.添加名字
UILabel *nameLabel = [[UILabel alloc] init];
// 设置位置
CGFloat nameW = appW;
CGFloat nameH = 20;
CGFloat nameX = 0;
CGFloat nameY = iconY + iconH;
nameLabel.frame = CGRectMake(nameX, nameY, nameW, nameH);
// 设置文字
nameLabel.text = appInfo.name;
// 设置字体
nameLabel.font = [UIFont systemFontOfSize:13];
// 设置文字居中对齐
nameLabel.textAlignment = NSTextAlignmentCenter;
[appView addSubview:nameLabel];
// 3.4.3.添加下载按钮
UIButton *downloadBtn = [[UIButton alloc] init];
// 设置位置
CGFloat downloadX = 12;
CGFloat downloadY = nameY + nameH;
CGFloat downloadW = appW - 2 * downloadX;
CGFloat downloadH = 20;
downloadBtn.frame = CGRectMake(downloadX, downloadY, downloadW, downloadH);
// 设置默认的背景
UIImage *normalImage = [UIImage imageNamed:@"buttongreen"];
[downloadBtn setBackgroundImage:normalImage forState:UIControlStateNormal];
// 设置高亮的背景
UIImage *highImage = [UIImage imageNamed:@"buttongreen_highlighted"];
[downloadBtn setBackgroundImage:highImage forState:UIControlStateHighlighted];
// 设置按钮的文字
[downloadBtn setTitle:@"下载" forState:UIControlStateNormal];
// 不推荐直接拿到按钮内部的label设置文字
// downloadBtn.titleLabel.text = @"5435345345";
// 设置按钮文字的字体
//@property(nonatomic,readonly,retain) UILabel *titleLabel NS_AVAILABLE_IOS(3_0);
// @property(nonatomic,readonly,retain) UIImageView *imageView stemFontOfSize:13];
downloadBtn.titleLabel.font = [UIFont systemFontOfSize:13];
[appView addSubview:downloadBtn];
}
}
- (NSArray *)apps
{
if (_apps == nil) {
// 初始化
// 1.获得plist的全路径
NSString *path = [[NSBundle mainBundle] pathForResource:@"app.plist" ofType:nil];
// 2.加载数组
NSArray *dictArray = [NSArray arrayWithContentsOfFile:path];
// 3.将dictArray里面的所有字典转成模型对象,放到新的数组中
NSMutableArray *appArray = [NSMutableArray array];
for (NSDictionary *dict in dictArray) {
// 3.1.创建模型对象
// MJApp *app = [[MJApp alloc] initWithDict:dict]; //调用模型的构造方法初始化模型的两个属性
MJApp *app = [MJApp appWithDict:dict]; //调用模型类的类方法初始化模型的两个属性
// 3.2.添加模型对象到数组中
[appArray addObject:app];
}
// 4.赋值
_apps = appArray;
}
return _apps;
}
@end
4.初始MVC
MVC是一种设计思想,贯穿于整个iOS开发中,需要积累一定的项目经验,才能深刻体会其中的含义和好处
MVC中的三个角色
M:Model,模型数据
V:View,视图(界面)
C:Control,控制中心
MVC的几个明显的特征和体现:
View上面显示什么东西,取决于Model
只要Model数据改了,View的显示状态会跟着更改
Control负责初始化Model,并将Model传递给View去解析展示
MVC中的三个角色
M:Model,模型数据
V:View,视图(界面)
C:Control,控制中心
MVC的几个明显的特征和体现:
View上面显示什么东西,取决于Model
只要Model数据改了,View的显示状态会跟着更改
Control负责初始化Model,并将Model传递给View去解析展示