一、懒加载
只有使用到了商品数组才会创建数组
保证数组只会被创建一次
只要能够保证数组在使用时才创建, 并且只会创建一次, 那么我们就称之为懒加载 lazy
- (void)viewDidLoad 控制器的view创建完毕就会调用,该方法只会调用一次
@property (nonatomic, strong)NSArray *shops; - (void)viewDidLoad { [super viewDidLoad]; if (self.shops == nil) { NSLog(@"创建商品数组"); self.shops = @[ @{@"name":@"单肩包", @"icon":@"danjianbao"}, @{@"name":@"链条包", @"icon":@"liantiaobao"}, @{@"name":@"钱包", @"icon":@"qianbao"}, @{@"name":@"手提包", @"icon":@"shoutibao"} ]; } }
二、plist文件
向plist文件写入
[_shops writeToFile:@"/Users/用户名/Desktop/shops.plist" atomically:YES]; _shops = [NSArray arrayWithContentsOfFile:@"/Users/用户名/Desktop/shops.plist"];
读取plist文件
// 1.获取plist文件的绝对路径 NSString *path = [[NSBundle mainBundle] pathForResource:@"shops.plist" ofType:nil]; // 2.根据路径加载plist文件 _shops = [NSArray arrayWithContentsOfFile:path];
注意点:
在自定义plist文件的时候, 一定不能将plist文件的名称命名为info.plist, 或者xxxxinfo.plist
也就是说自定义的plist文件的名称不能包含info这个单词
三、字典转模型
废话不多说,直接上代码
@interface ViewController () @property (nonatomic, strong)NSMutableArray *shops; @end /***************模型类***************/ @interface NJShop : NSObject // 商品名称 @property(nonatomic, copy)NSString *name; // 商品图片 @property(nonatomic, copy)NSString *icon; + (instancetype)shopWithDict:(NSDictionary *)dict; @end @implementation NJShop + (instancetype)shopWithDict:(NSDictionary *)dict { NJShop *shop = [[self alloc] init]; shop.name = dict[@"name"]; shop.icon = dict[@"icon"]; return shop; } @end @implementation ViewController // 重写getter方法 - (NSMutableArray *)shops { if (_shops == nil) { // 1.获取plist文件的绝对路径 NSString *path = [[NSBundle mainBundle] pathForResource:@"shops.plist" ofType:nil]; // 2.根据路径加载plist文件 NSArray *tempArr = [NSArray arrayWithContentsOfFile:path]; // 3.将数组中所有的字典转换为模型 _shops = [NSMutableArray array]; for (NSDictionary *dict in tempArr) { NJShop *shop = [NJShop shopWithDict:dict]; [_shops addObject:shop]; } } return _shops; } @end
在开发中一般不会直接从字典中获取数据
1.字典的key是一个字符串, 写错不会报错
2.英语不好, 单词记不住
3.由于key是一个字符串, 所以在编码的时候没有提示
为了解决这个问题, 我们可以使用对象来保存数据
1 // 1.创建一个父控件 2 UIView *containerView = [[UIView alloc] init]; 3 containerView.backgroundColor = [UIColor redColor]; 4 containerView.frame = CGRectMake(shopX, shopY, 70, 100); 5 6 // 2.创建一张图片 7 UIImageView *iv = [[UIImageView alloc] init]; 8 iv.frame = CGRectMake(0, 0, 70, 70); 9 10 // 3.创建一个文本 11 UILabel *lable = [[UILabel alloc] init]; 12 lable.frame = CGRectMake(0, 70, 70, 30); 13 lable.textAlignment = NSTextAlignmentCenter; 14 15 // 4.将图片和文本添加到父控件中 16 [containerView addSubview:iv]; 17 [containerView addSubview:lable]; 18 19 // 5.设置数据 20 NJShop *shop = self.shops[index]; 21 UIImage *image = [UIImage imageNamed:shop.icon]; 22 iv.image = image; 23 lable.text = shop.name;
如果当前对象的作用就是用于存储数据, 那么我称这个对象为模型
四、自定义view
1 @interface NJShopView : UIView 2 // 数据模型 3 @property(nonatomic, strong)NJShop *shop; 4 @end 5 6 7 @interface NJShopView () 8 // ARC中如果是strong, 对象就不会释放, 如果是weak对象会自动释放 9 // strong强指针 weak弱指针 10 11 @property(nonatomic, weak)UIImageView *iv; 12 13 @property(nonatomic, weak)UILabel *lable; 14 15 @end 16 17 @implementation NJShopView 18 19 - (instancetype)init 20 { 21 if (self = [super init]) { 22 // 注意: 如果自定义一个View, 不建议在init方法中设置子控件的位置 23 // 因为如果子控件的位置需要根据父控件的frame来计算, 在init方法中拿不到父控件的frame 24 25 // 1.创建一张图片 26 // 注意: 千万不能使用一个弱指针的属性直接保存一个控件 27 否则对象创建出来立刻就会被释放 28 // self.iv = [[UIImageView alloc] init]; 29 30 UIImageView *iv = [[UIImageView alloc] init]; 31 iv.backgroundColor = [UIColor yellowColor]; 32 // iv.frame = CGRectMake(0, 0, self.frame.size.width, self.frame.size.width); 33 [self addSubview:iv]; 34 // 这里可以使用weak的属性保存控件的原因, 是因为在前面已经将控件添加到父控件中了 35 只要将一个对象添加到父控件中, 那么父控件中的subViews数组就会强引用这这个控件 36 self.iv = iv; 37 38 // 2.创建一个文本 39 UILabel *lable = [[UILabel alloc] init]; 40 lable.backgroundColor = [UIColor purpleColor]; 41 // lable.frame = CGRectMake(0, self.frame.size.width, self.frame.size.width, self.frame.size.height - iv.frame.size.height); 42 lable.textAlignment = NSTextAlignmentCenter; 43 [self addSubview:lable]; 44 self.lable = lable; 45 } 46 return self; 47 } 48 49 // layoutSubviews方法是专门用于布局子控件的位置的 50 // 注意: 重写layoutSubviews方法, 一定要调用[super layoutSubviews]方法 51 如果不调用, 会出现一些奇葩的错误 52 - (void)layoutSubviews 53 { 54 [super layoutSubviews]; 55 56 CGFloat shopViewWidth = self.frame.size.width; 57 CGFloat shopViewHeight = self.frame.size.height; 58 // 1.布局图片的位置 59 self.iv.frame = CGRectMake(0, 0, shopViewWidth, shopViewWidth); 60 // 2.布局文本的位置 61 self.lable.frame = CGRectMake(0, shopViewWidth, shopViewWidth, shopViewHeight - self.iv.frame.size.height); 62 } 63 64 - (void)setShop:(NJShop *)shop 65 { 66 _shop = shop; 67 68 // 设置子控件的数据 69 self.iv.image = [UIImage imageNamed:_shop.icon]; 70 self.lable.text = _shop.name; 71 } 72 @end 73 74 @interface ViewController () 75 // 添加方法 76 - (IBAction)add; 77 // 移除方法 78 - (IBAction)remove; 79 // 商品容器 80 @property (weak, nonatomic) IBOutlet UIView *shopsView; 81 82 @property (weak, nonatomic) IBOutlet UIButton *removeBtn; 83 @property (weak, nonatomic) IBOutlet UIButton *addBtn; 84 85 @property (nonatomic, strong)NSMutableArray *shops; 86 @end 87 88 @implementation ViewController 89 90 - (IBAction)add 91 { 92 NJShopView *shopView = [[NJShopView alloc] init]; 93 shopView.backgroundColor = [UIColor redColor]; 94 // shopX, shopY 95 shopView.frame = CGRectMake(shopX, shopY, 70, 100); 96 [self.shopsView addSubview:shopView]; 97 98 // 设置数据 99 // [shopView setShop:self.shops[index]]; 100 shopView.shop = self.shops[index]; 101 } 102 103 // 重写getter方法 104 - (NSMutableArray *)shops 105 { 106 if (_shops == nil) { 107 NSLog(@"创建一个新的数组"); 108 // 1.获取plist文件的绝对路径 109 NSString *path = [[NSBundle mainBundle] pathForResource:@"shops.plist" ofType:nil]; 110 // 2.根据路径加载plist文件 111 NSArray *tempArr = [NSArray arrayWithContentsOfFile:path]; 112 113 // 3.将数组中所有的字典转换为模型 114 _shops = [NSMutableArray array]; 115 for (NSDictionary *dict in tempArr) { 116 NJShop *shop = [[NJShop alloc] init]; 117 shop.name = dict[@"name"]; 118 shop.icon = dict[@"icon"]; 119 [_shops addObject:shop]; 120 } 121 122 } 123 return _shops; 124 } 125 @end