iOS中常常遇到后端返回JSON出现null值问题

在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 替换成 @""

  1. 给 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
  1. 给 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

总结

  1. 后端返回的null → iOS 解析为NSNull,正则无法处理
  2. 递归替换类目 是 iOS 开发处理 null 的标准方案
  3. 正则只适合原始 JSON 字符串预处理
  4. 导入类目后,一行代码就能彻底解决崩溃问题
相关推荐
问心无愧05132 小时前
ctf show web入门90
前端·笔记
yingyima2 小时前
午夜惊魂:用 Shell 脚本和 Hey Cron 解决服务器定时报警
前端
青山Coding2 小时前
Cesium应用(五):通视分析,解锁三维场景的”无遮挡“视野
前端·cesium
JavaAgent架构师2 小时前
前端AI工程化(三):异步编程与并发控制
前端·人工智能
独泪了无痕2 小时前
利用vue-pdf-embed实现PDF文件的预览
前端·vue.js
Exploring2 小时前
Hola 计算器 v1.0.1 发布:个税计算全面升级,劳务报酬也能算清楚了!
前端
Pan Zonghui2 小时前
个人开源技术博客前端
前端·开源
kyriewen2 小时前
我让AI替我写Git提交信息,老板以为我每天工作16小时
前端·javascript·git