NSInvalidArgumentException 异常
1
-[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[3]
NSString *password = nil;
NSDictionary *dict = @{
@"userName": @"bruce",
@"password": password
};
NSLog(@"dict is : %@", dict);
出现原因:没有正确将后台返回的数据转为model,提供给对象使用,后台返回的数据有可能为空,就会造成nil对象
三种方案:
方案一:后台在返回数据的时候进行校验,对空值进行处理。但是在项目中有些空值是有特殊的用途,此种方案不可行。
方案二:在转换成NSDictionary的时候,对后台返回的数据进行校验,把空值转换成NSNull对象。方案可行,但是需要对现有代码做大的改动,每次转换的时候都需要进行校验,太麻烦。业务高速发展时期,这样做成本太高。
int 类型的对象转为NSNumber
方案三:有没有一种无须改动现有代码又能解决该问题呢?答案是有的,可以利用Objective-C的runtime来解决该问题。
NSDictionary插入nil对象会造成崩溃,但是插入NSNull对象是不会造成崩溃的,只要利用runtime的Swizzle Method把nil对象给转换成NSNull对象就可以把该问题给解决了。创建一个NSDictionary的类别,利用runtime的Swizzle Method来替换系统的方法。
源码实现可以参考Glow团队封装的NSDictionary+NilSafe(Github上可下载到)
2data parameter is nil
NSData *data = nil;
NSError *error;
NSDictionary *orginDict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&error];
NSLog(@"originDict is : %@", orginDict);
3 unrecognized selector sent to instance 0x15d23910
一个类调用了一个不存在的方法,造成的崩溃
可以在写一个方法的时候,判断一下其类的类型,不符合类型的不让其调用,也可以使用runtime对常见的方法调用做一下错误兼容。比如我这边经常会出现这样的崩溃:
当这些对象调用这几个不存在的方法的时候,替换成自己定义的一个方法,对它们做一下错误兼容,使应用不会崩溃
总结:造成NSInvalidArgumentException异常大概有以下原因:
NSDictionary插入nil的对象。NSMutableDictionary也是同样的道理。
NSJSONSerialization序列化的时候,传入data为nil。
an unrecognized selector 无法识别的方法