@interface ViewController ()
/** 所有的车数据*/
@property (nonatomic ,strong) NSArray *carGroups;
@end
@implementation ViewController
- (NSArray *)carGroups
{
if (!_carGoups) {
// 告诉MJExtension这个框架CarGroup的cars数组属性中装的是XMGCar 模型
[CarGroup mj_setupObjectClassInArray:^NSDictionary *{
return @{@"cars" : [Car class]};
}];
_carGoups = [CarGroup mj_objectArrayWithFilename:@"cars.plist"];
}
return _carGoups;
}
在控制台输出plist文件中的key(属性)
- 前提:plist中最外层为字典,但是只能获取到第一层的key属性(即模型中的属性),第二层获取不了)
- 注意:以后直接在项目中导入NSDictionary+PropertyCode.h好.m文件即可.用的时候直接输入ViewController.h中的这些代码即可
ViewController.h文件
NSString *fileName = [[NSBundle mainBundle] pathForResource:@"status.plist" ofType:nil];
// 获取字典
NSDictionary *dict = [NSDictionary dictionaryWithContentsOfFile:fileName];
[dict createPropetyCode];
NSDictionary+PropertyCode.h文件
#import <Foundation/Foundation.h>
@interface NSDictionary (PropertyCode)
// 生成属性代码
- (void)createPropetyCode;
@end
NSDictionary+PropertyCode.m文件
#import "NSDictionary+PropertyCode.h"
@implementation NSDictionary (PropertyCode)
// 私有API:真实存在,但是苹果没有暴露出来,不给你
// isKindOfClass:判断下是否是当前类或者子类
// 自动生成属性代码
- (void)createPropetyCode
{
// 模型中属性根据字典的key
// 有多少个key,生成多少个属性
NSMutableString *codes = [NSMutableString string];
// 遍历字典
[self enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull value, BOOL * _Nonnull stop) {
NSString *code = nil;
if ([value isKindOfClass:[NSString class]]) {
code = [NSString stringWithFormat:@"@property (nonatomic, strong) NSString *%@;",key];
} else if ([value isKindOfClass:NSClassFromString(@"__NSCFBoolean")]){
code = [NSString stringWithFormat:@"@property (nonatomic, assign) BOOL %@;",key];
} else if ([value isKindOfClass:[NSNumber class]]) {
code = [NSString stringWithFormat:@"@property (nonatomic, assign) NSInteger %@;",key];
} else if ([value isKindOfClass:[NSArray class]]) {
code = [NSString stringWithFormat:@"@property (nonatomic, strong) NSArray *%@;",key];
} else if ([value isKindOfClass:[NSDictionary class]]) {
code = [NSString stringWithFormat:@"@property (nonatomic, strong) NSDictionary *%@;",key];
}
// 拼接字符串
[codes appendFormat:@"\n%@\n",code];
}];
NSLog(@"%@",codes);
}
@end
如何打印出plist文件中的内容
最外层为数组
最外层为字典
MJ的字典转模型
- 字典转模型的含义:
- 字典:里面全都是key:value的形式
- 字典数组就是数组里面有字典,模型数组就是数组里面有模型.
- 字典数组转模型数组-->利用kvc思想,即一个key对应一个value的形式把字典中的数据写到模型中
- 字典转模型 字典的含义:要转换的数据必须是字典。
- 字典转模型:把字典里的数据转成模型
- 拓展:plist文件的root只有一个,不能有多个。
- 例如root为字典,那么这里面可以有很多字典,也可以装很多数组,里面的这些字典和数组就不是root了,他们在root下。
- 字典转模型,最终操作的是字典D。无论这个字典D的上一层是数组还是字典,你能拿到字典D的上一层中就行。你必须在字典D的上一层来操作字典D,你必须在字典D的上一层来操作字典D,你必须在字典D的上一层来操作字典D,能拿到字典D的上一层,那么你就可以字典转模型了(重要的事情说三遍).
- MJ框架常用的方法是:字典的上一层是数组。开发中,上一层一般是数组。谁闲着没事,搞那么繁琐,当然是越简单越好.
MJ框架应用场景:
- 1:最外层为数组+数组里面是全是字典:直接用: [类名 mj_objectArrayWithFilename:@"aa.plist"];
- 2:最外层是字典,字典中装的key是数组,value就是数组中全部的内容(不是具体哪一个,看其他场景1你就知道了),用:self.topics = [类名 mj_objectArrayWithKeyValuesArray:responseObject[@"数组名"]];
- responseObject[@"数组名"]中的responseObject是字典,整体是数组。
- 这个方法硬性要求:必须把范围先精确到数组(为的是让这个数组作为这个方法的参数),才能操作数组中的字典(mj底层帮我们实现)。
- 2方法的使用范围:字典的父层必须是数组。否则这个方法不能用。因为这个方法就是让你传数组作为这个方法作为参数,默认要求让你这个数组里面必须装的是字典。
MJ 字典转模型和普通字典转模型的精华区别
- 普通字典:用对服务器或者plist中的这四个key:A,B,C,D进行字典转模型,如果模型中声明了A,B,C,但是没有声明D,就会报错。解决办法:在模型类的.m文件重写setValue:forUndefinedKey:方法,然后什么也不做
- MJ的字典转模型,如果也是上面那种情形,MJ底层自动给你写了这个方法,所以不用担心上面那个问题了
转一层
转两层
其他场景1(详细看截图左侧的注释)
其他场景2(注释太给力了,太精华了)
其他场景,注意理解
普通字典转模型
- 普通字典转模型,必须在模型中.h文件中声明一个方法供外界调用,最好是类方法,另外参数必须是字典类型的。因为字典转模型,你得把字典传进模型的类中啊(精华),这样才能把字典中的key赋值给模型中的key,不然你怎么转?
- for (NSDictionary *carGroupDict in dictArray)的含义:
-遍历dictArray数组中的每一个对象,因为知道了每一个对象是字典类型,所以用NSDictionary类型的carGroupDict保存每一个遍历出来的对象