1、[str containsString book_id] crash 因为后台使用 id定义字段 ,后台默认给的是 int,本人以book_id 解析该字段,不巧模型的数据类型定义为了Str,因此在解析是不会出错,赋值也不会出错,但如果如果对该字段使用Str的方法时,Crash了,原因是数据类型不匹配。
2、修改接收之前变量的类型为 NSInteger 结果还是发现,如果把此 interger 赋值给字典的Value 时,值发生了改变。
3、将该字段数据类型修改为 NSNumber 结果还是一样;
4、之前方法是这样的
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
if([key isEqualToString:@"id"]){
self.book_id = value;
}
}
于是根据定义的字段类型修改了此方法
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
if([key isEqualToString:@"id"]){
self.book_id = [value integerValue];
}
}
可以正常赋值给字典;
5、思考一个问题,model中有一个变量也是NSInteger类型,但是赋值正常,猜想是不是赋值方法有问题。
6、于是保持第4步修改,将变量修改为NSInteger,可以正常赋值给字典;
7、为了保持通用性,将setValue forUndefinedKey方法优化
- (void)setValue:(id)value forUndefinedKey:(NSString *)key{
if([key isEqualToString:@"id"]){
[self setValue:value forKey:@"book_id"];
}
} 可以正常赋值
8、此时,在想这个setValue forKey 的方法是不是可以把 服务器端的int 强转为NSString呢?当然,很早学习iOS时,我们是有答案的,不行,不过,好奇心的驱使下,我还是将该字段类型改为最初的NSString.果然,如果不调用containsString 方法,是没毛病的。只要调用,必然crash.
9、显然是类型不对,于是再次在setForUndefinedKey 方法了转了一次数据类型
- (void)setValue:(id)value forUndefinedKey:(NSString*)key{
if([key isEqualToString:@"id"]){
// self.book_id = [value integerValue];
// self.book_id = value;
// [self setValue:value forKey:@"book_id"];
NSString *strValue = [NSString stringWithFormat:@"%ld",[value integerValue]];
[selfsetValue:strValueforKey:@"book_id"];
}
}
于是,到调用containsString 方法那里打了断点,看到了运行时此字段的数据类型:NSTaggedPointerString.当然此处不再Crash。
如果不转数据类型,直接使用
[self setValue:value forKey:@"book_id"];则该字段的数据类型为:CFNumber 调用containsString 必然Crash.
总结:SetValue for UndefindeKey方法使用也是有技巧的。
1、如果想与后台保持数据类型一致,那么请使用保证模型的类型与后台类型一致,且注意赋值方式,尽量使用 SetValueFor Key。
2、如果执意要更改该字段数据类型。赋值前,请强转。