项目中创建数据模型有时候是必不可少的,而有时候或因为后台返回数据没有相对应的值,并且在后期如果使用该模型中属性会使程序崩溃。
我的习惯是创建模型时就俩种属性举个例子这就是UserModel
@property(nonatomic,strong)NSNumber *userId;
@property(nonatomic,copy)NSString *userNickName;
如何在某个网络请求用到了UserModel来接受网络请求下来的数据,而请求下来的数据并没有返回userId,但你却在项目中使用了这个属性,就会引起行么奔溃所以要对模型进行一下处理,使他们在初始化得时候就有了初始值,这样不会引发程序崩溃,解决办法为写一个BaseModel根模型类,让所有的模型类继承于它,我们在这个BaseModel中用runTime机制来处理初始值问题,在.m中重写init方法
- (instancetype)init
{
self = [super init];
if (self) {
Class tempClass = [self class];
while (tempClass != [NSObject class]) {
//计数变量
unsigned int count = 0 ;
//获取类的属性列表 后面方法俩个参数,一个是类型变量,一个是计数变量地址
objc_property_t *propertyList = class_copyPropertyList(tempClass, &count);
//遍历属性列表
for (int i = 0; i < count; i ++) {
objc_property_t property = propertyList[i];
//获取每个属性的名称
NSString *propertyName = [NSString stringWithUTF8String: property_getName(property)];
//获取属性的类型
const char * type = property_getAttributes(property);
//转码成oc字符串格式
NSString *attr = [NSString stringWithCString:type encoding:NSUTF8StringEncoding];
//打印attr就会发现里面包含的字符串规律
if ([attr hasPrefix:@"T@"] && [attr length] > 1) {
NSString * typeClassName = [attr substringWithRange:NSMakeRange(3, [attr length]-4)];
//处理NSString类型 付初值@""
if ([typeClassName containsString:@"NSString"]) {
[self setValue:@"" forKey:propertyName];
}
//处理NSNumber类型 付初值@(0)
if ([typeClassName containsString:@"NSNumber"]) {
[self setValue:@(0) forKey:propertyName];
}
Class typeClass = NSClassFromString(typeClassName);
if (typeClass != nil) {
// Here is the corresponding class even for nil values
}
}
}
free(propertyList);
tempClass = [tempClass superclass];
}
}
return self;
}