Objective-C中的非空违规检测

时间:2016-02-05 19:24:06

标签: objective-c nullable

我有一些这样的代码,我声明一个具有非空属性的对象

@interface HelloObject : NSObject
@property (nonatomic,strong,nonnull) NSString *foo;
@property (nonatomic,strong,nonnull) NSString *bar;

-(instancetype _Nullable)initWithJson:(nonnull NSDictionary*)json;
@end

然后从JSON初始化对象我使用此代码:

-(instancetype _Nullable)initWithJson:(nonnull NSDictionary*)json
{
    if( (self = [super init]) ) {
        _bar = json[@"bar"];
        _foo = json[@"foo"];
    }

    return self;
}

服务器可能向我发送了格式错误的JSON。例如," foo"字段可能会丢失。检查nil并返回nil很容易,但是我有很多这样的代码,它会不够优雅且容易出错。

是否有简单而优雅的方法来检查对象是否在运行时违反了其非空声明?例如,我不想写这样的代码:

        barX = json[@"bar"];
        if (barX) {
            _bar = barX;
        } else {
            return nil;
        }

那丑陋和样板(因此容易出错)。我更喜欢这样的东西:

    if (![self ValidForNonNulls]) {
        return nil;
    }

但我无法想到为一般对象编写ValidForNonNulls的方法。

1 个答案:

答案 0 :(得分:2)

我不认为尝试解决nil的测试需求在Objective-C中是切实际的。

如果我必须验证很多此类传入的术语,并且我需要检查它们的有效性或返回nil,那么我会重写我的initWithJson方法进行检查,并使用类别来保留代码清晰可读。

- (instancetype _Nullable)initWithJSON:(nonnull NSDictionary *)json
{
    if ( (self = [super init]) ) {
        if ( ![json hasValuesForKeys:@[@"foo", @"bar"]] ) {
            //Consider logging this as an error
            return nil;
        }

        _bar = json[@"bar"];
        _foo = json[@"foo"];
    }

    return self;
}

...

@interface NSDictionary (hasValuesForKeys)
- (BOOL)hasValuesForKeys:(NSArray *)keys;
@end

@implementation

- (BOOL)hasValuesForKeys:(NSArray *)keys
{
    for (NSString *key in keys) {
        if ( !self[key] || [self[key] isEqual:[NSNull null]] ) {
            return NO;
        }
    }

    return YES;
}

@end

如果您需要验证它们是否为NSNumber,则可以为每个值进行更具体的测试。