/* 1. - 懒加载 (掌握) */
- 作用:
+ 用到时再加载
+ 保证数据只会被加载一次
- 好处:
+ 节约内存空间
```objc
@interface ViewController ()
@property (nonatomic, strong)NSArray *shops;
@end
@implementation ViewController
// 重写getter方法
- (NSArray *)shops
{
if (_shops == nil) {
NSLog(@"创建一个新的数组");
_shops = @[
@{@"name":@"单肩包",
@"icon":@"danjianbao"},
@{@"name":@"链条包",
@"icon":@"liantiaobao"},
@{@"name":@"钱包",
@"icon":@"qianbao"},
@{@"name":@"手提包",
@"icon":@"shoutibao"}
];
}
return _shops;
}
@end
```
---
/* 2. - plist文件 (掌握) */
-作用:
+ 将数据和逻辑分离
+ 提高了代码的扩展性
- 获取plist文件的绝对路径
```objc
NSBundle *bundle = [NSBundle mainBundle];
NSString *path = [bundle pathForResource:@"shops" ofType:@"plist"];
```
- 注意点:
+ 文件名称中不能包含info单词
---
/* 3. - 字典转模型 */
- 字典的弊端
+ 1.字典的key是一个字符串, 写错不会报错
+ 2.英语不好, 单词记不住
+ 3.由于key是一个字符串, 所以在编码的时候没有提示, 编码效率比较低
- 模型的优点
+ 可以通过属性来获取值, 属性写错会报错
+ 不用去记单词, 只需要记住以什么开头即可
+ 由于属性有提示, 所以编码效率比较高
- 注意:
+ 字典转模型的操作应该封装到模型中
+ 如果不封装在模型中的弊端:
* 如果有很多地方都需要字典转模型, 那么很多地方都需要写重复的代码
* 需求变更所有字典转模型的地方都需要修改
```objc
+ (instancetype)shopWithDict:(NSDictionary *)dict
{
NJShop *shop = [[self alloc] init];
shop.name = dict[@"name"];
shop.icon = dict[@"icon"];
return shop;
}
```
- 规律:
+ 在开发中但凡看到字典,一般情况下都会创建一个与之对应的模型来保存字典中的数据
- 模型的类名命名注意:
+ 一般情况下在自定义一个类的时候会给每个类添加一个"类前缀", 这样可以避免多人开发发生冲突
// 4. - 自定义View
- 目的:
+ 提高代码的复用性
+ 屏蔽内部的实现细节
- 步骤:
+ 1.自定义一个类继承于UIView
+ 2.在initWithFrame方法中添加子控件
+ 3.在layoutSubviews中设置子控件的位置
+ 4.提供一个属性保存外界传入的数据(模型对象), 重写setter方法设置子控件的数据
- 类工厂方法(便利构造器)
+ 按照苹果的风格和规范, 一般情况一个用于创建对象的对象方法会对应一个类方法
+ 可以通过类工厂方法, 快速的根据数据创建一个对象
- 注意点:
+ 返回值一定要使用instancetype, 不要使用id
+ 在类工厂方法中创建对象, 使用self, 不要使用类名
---
/* 5.- layoutSubviews */
- 作用:
+ 布局子控件, 用于调整子控件的位置
- 什么时候调用
+ 控件第一次被创建
+ 控件的尺寸(size)被修改会调用
- 注意点:
+ 重写layoutSubviews方法, 一定要调用父类的方法
---
/* 6. - Xib */
- 什么是Xib
+ Xib和Storyboard一样都是用来描述界面的
+ Xib是Storyboard的前身
- Xib和storyboard对比
- 共同点:
+ 都用来描述软件界面
+ 都用Interface Builder工具来编辑
+ 本质都是转换成代码去创建控件
- 不同点
+ Xib是轻量级的,用来描述局部的UI界面
+ Storyboard是重量级的,用来描述整个软件的多个界面,并且能展示多个界面之间的跳转关系
- 如何加载xib
- 第一种方式
```objc
NSArray *views = [[NSBundle mainBundle] loadNibNamed:@"xib文件名" owner:nil options:nil]
```
- 第二种方式
```objc
UINib *nib = [UINib nibWithNibName:@"xib文件名" bundle:nil];
NSArray *views = [nib instantiateWithOwner:nil options:nil];
```
- 规律
+ 一般情况下苹果的方法中要求传入一个bundle参数, 直接传nil就代表mainBundle
---
/* 7. - 利用Xib自定义View */
- 步骤
+ 1.新建一个Xib描述界面
+ 2.新建一个继承于Xib界面中父控件类型的类来管理界面
+ 3.在xib中关联界面和类
+ 4.重写awakeFromNib方法, 进行一些初始化
+ 5.提供一个属性保存外界传入的数据(模型对象), 重写setter方法设置子控件的数据
- 注意点:
- 不应该在控制器中加载xib, 应该将加载xib的操作封装到自定义view中
```objc
+ (instancetype)shopView
{
return [[[NSBundle mainBundle] loadNibNamed:@"XMGShopView" owner:nil options:nil] firstObject];
}
```
- 方法的执行顺序
+ 如果是通过xib或者Storyboard创建一个控件, 不会调用initWithFrame方法
+ 在"创建时"会调用initWithCoder方法
* 控件不一定被创建好了
+ 在"创建后"会调用awakeFromNib
* 控件一定被创建好了
---
/* 8. - xib原理 */
+ 1. 根据custom class创建对象
```
XMGShopView *shopView = [XMGShopView alloc] init];
```
+ 2. 根据xib中的设置, 设置控件的相关属性
```
shopView.backgroundColor = [UIColor redColor];
shopView.frame = CGRectMake(0, 0, 70, 100);
```
+ 3. 创建所有子控件, 并且设置子控件的属性
```
UIImageView *iv = [[UIImageView alloc] init];
iv.frame = CGRectMake(0, 0, 70, 70);
UILabel *label = [[UILabel alloc] init];
label.frame = CGRectMake(0, 70, 70, 30);
```
+ 4. 检查子控件是否有连线, 如果有就进行关联
```
self.iconView = iv;
self.nameLabel = label;
```
+ 5.将所有子控件添加到父控件中
```
[shopView addSubview:iv];
[shopView addSubview:label];
```
/* 9. - MVC */
+ M --> Model --> 专门用于保存数据
+ V --> View --> 专门用户展示数据
+ C --> Controller -->专门用于编写逻辑代码(赋值管理M和V)
- 总统管理国家的例子
+ 如果一个人管理, 那么就累死了
+ 分级管理, 各司其职