加载plist文件的过程
- 1.先获取主资源包:
NSBundle *bundle = [NSBundle mainBundle];
- 2.利用主资源包获取plist文件的全路径:
NSString *file = [bundle pathForResource:@"shops" ofType:@"plist"];
- 3.利用全路径加载plist文件:
NSArray = [NSArray arrayWithContentsOfFile:file];
懒加载的使用
- 懒加载就是在真正使用到文件资源时才将文件资源加载、并且只加载一次;
- 一般情况下我们通过重写相应的get方法来实现懒加载(在get方法中加载);
例如:
- 1.我们在这里使用到了plist文件的内容:
NSDictionary *dic = self.shopsArray[index]; // 就是这里用到了shops.plist文件,用懒加载的话就重写shopsArray的get方法(self.shopsArray就是get方法),我们在shopsArray的get方法中加载就是懒加载,而不是已启动就加载文件,仅仅是用到了的时候才加载
- 1.我们在这里使用到了plist文件的内容:
2.我们通过重写shopsArray的get方法来实现懒加载:
- (NSArray *)shopsArray { if (_shopsArray == nil) { // 只加载一次 NSBundle *bundle = [NSBundle mainBundle]; NSString *file = [bundle pathForResource:@"shops" ofType:@"plist"]; _shopsArray = [NSArray arrayWithContentsOfFile:file]; } return _shopsArray; }
添加自定义代码块
- <#XXX#> : 里面的XXX会以提示效果显示
/** <#商品名称#> */
@property (strong, nonatomic) <#Class#> <#name#>;
模型的使用
- 所谓模型,其实就是数据模型,专门用来存放数据的对象,用它来表示数据会更加专业;
模型的好处:
- 模型设置数据和取出数据都是通过它的属性,属性名如果写错了,编译器会马上报错,因此,保证了数据的正确性
- 使用模型访问属性时,编译器会提供一系列的提示,提高编码效率
模型的使用步骤:
1.建一个模型类(ZYCShop),类里面添加相应的属性(_name和_icon);
@interface ZYCShop : NSObject // 模型类直接继承NSObject @property (strong, nonatomic) NSString *icon; // 商品图片 @property (strong, nonatomic) NSString *name; // 商品名称 - (instancetype)initWithDictionary:(NSDictionary *)dic; + (instancetype)shopWithDictionary:(NSDictionary *)dic;
2.自定义构造方法(对象方法和类方法),传入的数据可以是plist文件数据:
- (instancetype)initWithDictionary:(NSDictionary *)dic { if (self = [super init]) { _icon = dic[@"icon"]; _name = dic[@"name"]; } return self; } + (instancetype)shopWithDictionary:(NSDictionary *)dic { return [[self alloc] initWithDictionary:dic]; }
3.将原始数据(例如plist文件)转换成模型,并与原始数据类型一致
NSArray *dictArray = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"shops" ofType:@"plist"]]; // 加载plist文件中的数据(数组对象) NSMutableArray *shopArray = [NSMutableArray array]; // 创建一个可变数组用来存储转换后的模型 for (NSDictionary *dict in dictArray) { // 遍历原始数据 XMGShop *shop = [XMGShop shopWithDict:dict]; // 将原始数据转换成模型 [shopArray addObject:shop]; // 将转换后的模型数组添加到一个新的数组中 }
4.使用模型数据(不在使用原始的数据),利用模型对象.属性访问;
dict[@"name"]; // 原始访问方法 shop.name; // 转换后的模型访问方法
id和instancetype
instancetype
在类型表示上,跟id
一样,可以表示任何对象类型instancetype
只能用在返回值类型上,不能像id
一样用在参数类型上instancetype
比id
多一个好处:编译器会检测instancetype
的真实类型
自定义控件
如果想让子控件添加到自定义控件内部,三大步骤:
1.在自定义控件初始化的时候,添加子控件,一般重写initWithFrame:方法;也可以考虑
懒加载
!/*自定义控件类的.m文件*/ - (instancetype)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:(CGRect)frame]) { self.backgroundColor = [UIColor orangeColor]; // 创建一个view,并加载进商品展示view(自定义) UIImageView *iconView = [[UIImageView alloc] init]; iconView.backgroundColor = [UIColor redColor]; [self addSubview:iconView]; self.iconView = iconView; // 创建一个view,并加载进商品图片的view(为了不影响当前商品的index) UILabel *label = [[UILabel alloc] init]; label.font = [UIFont systemFontOfSize:12]; label.textAlignment = NSTextAlignmentCenter; label.backgroundColor = [UIColor magentaColor]; // 洋红色 [self addSubview:label]; self.nameLabel = label; } return self; }
2.在- (void)layoutSubview方法中布局子控件,当控件本身的尺寸发生变化时,系统就会自动调用layoutSubview方法;
/*自定义控件类的.m文件*/ - (void)layoutSubviews { [super layoutSubviews]; // 一定要调用[super layoutSubview]; CGFloat shopW = self.frame.size.width; CGFloat shopH = self.frame.size.height; self.iconView.frame = CGRectMake(0, 0, shopW, shopW); self.nameLabel.frame = CGRectMake(0, shopW, shopW, shopH - shopW); }
3.重写模型的set方法,拿到模型数据赋值给子控件
1.先在自定义控件类的.h文件中添加一个模型属性(shop); 2.再在自定义控件类的.m文件中重写模型的set方法,拿到模型数据并赋值给子控件 /*自定义控件类的.m文件*/ // 重写模型的set方法 - (void)setShop:(ZYCShop *)shop { _shop = shop; self.nameLabel.text = shop.name; // 给子控件赋值 self.iconView.image = [UIImage imageNamed:shop.icon]; // 给子控件赋值 }