前言:AFNetworking是我们常用的三方库,我们需要对请求下来的responceObject进行操作,很多时候我们不能与后台协商一致,或者做到完美过滤,就会导致程序崩溃。比如后台默认数据是个数组,但是给了个字符串或者空值,这时候你再去调用array.count,就会导致crash。为了避免这类错误,就需要全面的对数据进行过滤。
对于此类判断数组是否为空,很多人给出的方法
if (array != nil && ![array isKindOfClass:[NSNull class]] && array.count != 0){
//执行array不为空时的操作
}
严格来说这样的判断是错误的,当array不是[NSArray class]的时候,调用array.count就会crash
下面我们来做个实验
NSObject *obj = [NSObject new];
NSArray *array = (NSArray *)obj;
NSLog(@"---%@",array);
NSLog(@"---%ld",array.count);
输出
---<NSObject: 0x600001dcc2d0>
-[NSObject count]: unrecognized selector sent to instance 0x600001dcc2d0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSObject count]: unrecognized selector sent to instance 0x600001dcc2d0'
当用array接收一个对象,(NSArray *)并不能强制转换,只是告诉编译器你的接收对象是[NSArray class],顶多消除个警告罢了。这就导致了当你用数组接收responceObject某个字段对应的数据的时候报错。你以为你把数据转换成了[NSArray class],然而并没有
举例
NSDictionary *dic = @{@"a": @"123"};
NSArray *array = (NSArray *)dic[@"a"];
NSLog(@"---%@",array);
---123
可见接收对象是个字符串。如果这时候调用array.count,肯定会crash。
所以在调用array.count或者其他数组的方法的时候,最好判断这个对象是否是[NSArray class]
下面是我的方法
#pragma mark 判断是否是数组
+(BOOL)isArray:(NSArray *)array{
if (array == nil) {
return NO;
}
if ([array isKindOfClass:[NSNull class]]) {
return NO;
}
if (![array isKindOfClass:[NSArray class]]){
return NO;
}
return YES;
}
同理判断是否是字典,字符串也是大同小异
#pragma mark 判断是否是字典
+(BOOL)isDictionary:(NSDictionary *)dic{
if (dic == nil) {
return NO;
}
if ([dic isKindOfClass:[NSNull class]]) {
return NO;
}
if (![dic isKindOfClass:[NSDictionary class]]){
return NO;
}
return YES;
}
#pragma mark 判断是否是字符串
+(BOOL)isString:(NSString *)string{
if (string == nil) {
return NO;
}
if ([string isKindOfClass:[NSNull class]]) {
return NO;
}
if (![string isKindOfClass:[NSString class]]){
return NO;
}
if ([string isEqualToString:@"null"]) {
return NO;
}
if ([string isEqualToString:@"<null>"]) {
return NO;
}
return YES;
}
以上就是我总结的方法,仅供参考,如果有未考虑到位的地方,欢迎指出,谢谢