在iOS开发过程中经常需要与服务器进行数据通讯,Json就是一种常用的高效简洁的数据格式。往往后端返回的数据会出现null值,会被解析成NSNull对象,直接调用字符串 / 数组 / 字典方法会直接崩溃。如下:
json
"data":null
解决方法有两个
第一个解决方案:
通过写宏进行值替换
ini
#define VerifyValue(value)
({id tmp;
if ([value isKindOfClass:[NSNull class]])
tmp = nil;
else
tmp = value;
tmp;
})
第二个解决方案:
使用AFNetwork自带的方法解决
(终极方案终于找到了一劳永逸的方案,牛逼的老外写了一个Category,叫做NullSafe ,在运行时操作,把这个讨厌的空值置为nil,而nil是安全的,可以向nil对象发送任何message而不会奔溃。这个category使用起来非常方便,只要加入到了工程中就可以了,你其他的什么都不用做,对,就是这么简单)
ruby
self.removesKeysWithNullValues = YES;
5、终极方案终于找到了一劳永逸的方案,牛逼的老外写了一个Category,叫做NullSafe ,在运行时操作,把这个讨厌的空值置为nil,而nil是安全的,可以向nil对象发送任何message而不会奔溃。这个category使用起来非常方便,只要加入到了工程中就可以了,你其他的什么都不用做,对,就是这么简单。详细的请去Github上查看;[https://github.com/nicklockwood/NullSafe](https://github.com/nicklockwood/NullSafe)
第三个解决方案:
通过NSJSONSerialization调用JSONObjectWithData方法
ini
// 1. 解析后端JSON
NSDictionary *originalDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
// 2. 一键替换所有 null → ""
NSDictionary *safeDict = [originalDict replaceNullWithEmptyString];
// 3. 永远不会因为 null 崩溃
NSString *name = safeDict[@"name"];
第四个解决方案:
纯字符串场景:用正则替换 null 为 "",如果后端返回的是原始 JSON 字符串,里面直接写了null,可以用正则表达式全局替换: 正则规则 匹配独立的 null 单词(避免误替换包含 null 的单词):
swift
// 原始后端返回字符串
NSString *jsonString = @"{\"name\":null,\"age\":18,\"address\":\"null street\"}";
// 正则替换:所有独立的 null 替换为空字符串 ""
NSError *error = nil;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\bnull\\b"
options:0
error:&error];
NSString *result = [regex stringByReplacingMatchesInString:jsonString
options:0
range:NSMakeRange(0, jsonString.length)
withTemplate:@"\"\""];
NSLog(@"替换后:%@", result);
第五个解决方案:
写一个类目(Category),递归遍历字典 / 数组,把所有 NSNull 替换成 @""
- 给 NSDictionary 写类目(最实用) NSDictionary+NullReplace.h
objectivec
#import <Foundation/Foundation.h>
@interface NSDictionary (NullReplace)
- (NSDictionary *)replaceNullWithEmptyString;
@end
NSDictionary+NullReplace.m
objectivec
#import "NSDictionary+NullReplace.h"
@implementation NSDictionary (NullReplace)
- (NSDictionary *)replaceNullWithEmptyString {
NSMutableDictionary *mutDict = [self mutableCopy];
// 遍历所有key
[mutDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
// 1. 如果是 NSNull → 替换为空字符串
if ([obj isKindOfClass:[NSNull class]]) {
mutDict[key] = @"";
}
// 2. 如果是子字典 → 递归处理
else if ([obj isKindOfClass:[NSDictionary class]]) {
mutDict[key] = [obj replaceNullWithEmptyString];
}
// 3. 如果是数组 → 单独处理数组
else if ([obj isKindOfClass:[NSArray class]]) {
mutDict[key] = [obj replaceNullWithEmptyString];
}
}];
return [mutDict copy];
}
@end
- 给 NSArray 写类目 NSArray+NullReplace.h
objectivec
#import <Foundation/Foundation.h>
@interface NSArray (NullReplace)
- (NSArray *)replaceNullWithEmptyString;
@end
NSArray+NullReplace.m
ini
#import "NSArray+NullReplace.h"
#import "NSDictionary+NullReplace.h"
@implementation NSArray (NullReplace)
- (NSArray *)replaceNullWithEmptyString {
NSMutableArray *mutArray = [self mutableCopy];
// 遍历数组元素
for (int i = 0; i < mutArray.count; i++) {
id obj = mutArray[i];
if ([obj isKindOfClass:[NSNull class]]) {
mutArray[i] = @"";
}
else if ([obj isKindOfClass:[NSDictionary class]]) {
mutArray[i] = [obj replaceNullWithEmptyString];
}
else if ([obj isKindOfClass:[NSArray class]]) {
mutArray[i] = [obj replaceNullWithEmptyString];
}
}
return [mutArray copy];
}
@end
总结
- 后端返回的
null→ iOS 解析为NSNull,正则无法处理 - 递归替换类目 是 iOS 开发处理 null 的标准方案
- 正则只适合原始 JSON 字符串预处理
- 导入类目后,一行代码就能彻底解决崩溃问题