? 項(xiàng)目中創(chuàng)建數(shù)據(jù)模型有時(shí)候是必不可少的,而有時(shí)候或因?yàn)楹笈_(tái)返回?cái)?shù)據(jù)沒(méi)有相對(duì)應(yīng)的值,并且在后期如果使用該模型中屬性會(huì)使程序崩潰。
?我的習(xí)慣是創(chuàng)建模型時(shí)就倆種屬性舉個(gè)例子這就是UserModel
@property(nonatomic,strong)NSNumber *userId;
@property(nonatomic,copy)NSString *userNickName;
如何在某個(gè)網(wǎng)絡(luò)請(qǐng)求用到了UserModel來(lái)接受網(wǎng)絡(luò)請(qǐng)求下來(lái)的數(shù)據(jù),而請(qǐng)求下來(lái)的數(shù)據(jù)并沒(méi)有返回userId,但你卻在項(xiàng)目中使用了這個(gè)屬性,就會(huì)引起行么奔潰所以要對(duì)模型進(jìn)行一下處理,使他們?cè)诔跏蓟脮r(shí)候就有了初始值,這樣不會(huì)引發(fā)程序崩潰,解決辦法為寫一個(gè)BaseModel根模型類,讓所有的模型類繼承于它,我們?cè)谶@個(gè)BaseModel中用runTime機(jī)制來(lái)處理初始值問(wèn)題,在.m中重寫init方法
- (instancetype)init
{
self = [super init];
if (self) {
Class tempClass = [self class];
while (tempClass != [NSObject class]) {
//計(jì)數(shù)變量
unsigned int count = 0 ;
//獲取類的屬性列表 后面方法倆個(gè)參數(shù),一個(gè)是類型變量,一個(gè)是計(jì)數(shù)變量地址
objc_property_t *propertyList = class_copyPropertyList(tempClass, &count);
//遍歷屬性列表
for (int i = 0; i < count; i ++) {
objc_property_t property = propertyList[i];
//獲取每個(gè)屬性的名稱
NSString *propertyName = [NSString stringWithUTF8String: property_getName(property)];
//獲取屬性的類型
const char * type = property_getAttributes(property);
//轉(zhuǎn)碼成oc字符串格式
NSString *attr = [NSString stringWithCString:type encoding:NSUTF8StringEncoding];
//打印attr就會(huì)發(fā)現(xiàn)里面包含的字符串規(guī)律
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;
}