You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Objective-C如何避免大量if语句检查对象类型

嘿,这种层层嵌套的“厄运金字塔”确实写起来闹心,我给你分享几个能把代码捋清爽的实用技巧,都是OC原生就能实现的:

1. 写个通用的安全取值分类

最省心的方式是给NSObject加个分类,封装“按键路径取值+类型校验”的逻辑,以后所有地方都能复用:

@interface NSObject (SafeValueAccess)
// 根据键路径取值,并校验是否为指定类型,符合则返回,否则返回nil
- (nullable id)safeValueForKeyPath:(NSString *)keyPath ofClass:(Class)expectedClass;
@end

@implementation NSObject (SafeValueAccess)
- (nullable id)safeValueForKeyPath:(NSString *)keyPath ofClass:(Class)expectedClass {
    if (!keyPath || !expectedClass) return nil;
    
    id result = [self valueForKeyPath:keyPath];
    return [result isKindOfClass:expectedClass] ? result : nil;
}
@end

用这个分类重构你的代码,瞬间告别嵌套:

NSString *text = @"";
id json = [NSJSONSerialization JSONObjectWithData:[data dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];

// 先取data.value数组,校验类型
NSArray *valueArray = [json safeValueForKeyPath:@"data.value" ofClass:[NSArray class]];
if (valueArray) {
    // 这里注意:原代码里[value valueForKey:@"url"]返回的是数组(数组每个元素的url集合),如果要取单个元素的url,应该用firstObject
    NSString *url = [valueArray.firstObject safeValueForKeyPath:@"url" ofClass:[NSString class]];
    if (url) text = url;
}

2. 用“Guard宏”模拟Swift的提前退出

如果你不想写分类,还可以用宏来模拟Swift里的guard语句,把嵌套的条件判断平铺成顺序执行的检查,不满足就提前跳出:

// 定义Guard宏:条件不满足时执行block并退出当前方法
#define Guard(condition, exitBlock) if (!(condition)) { exitBlock; return; }

重构后的代码就变成了线性逻辑,没有多层缩进:

NSString *text = @"";
id json = [NSJSONSerialization JSONObjectWithData:[data dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];

// 逐层检查,不满足就直接返回
Guard([json isKindOfClass:[NSDictionary class]], { return; });
NSDictionary *jsonDict = (NSDictionary *)json;

Guard([jsonDict[@"data"] isKindOfClass:[NSDictionary class]], { return; });
NSDictionary *dataDict = jsonDict[@"data"];

Guard([dataDict[@"value"] isKindOfClass:[NSArray class]], { return; });
NSArray *valueArray = dataDict[@"value"];

// 原代码这里有个小问题:数组调用valueForKey:@"url"返回的是数组,不是单个NSString,所以调整为取第一个元素的url
id urlObj = valueArray.firstObject[@"url"];
Guard([urlObj isKindOfClass:[NSString class]], { return; });
text = (NSString *)urlObj;

额外小提示

原代码里[value valueForKey:@"url"]如果value是NSArray,返回的是所有元素的url组成的数组,这时候判断它是NSString永远不会成立,应该是你想取数组里某个元素的url(比如第一个),记得调整这部分逻辑哦~

内容的提问来源于stack exchange,提问作者Curt Rand

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:19:20