Objective-C 中的非空违规检测

Nonnull violation detection in Objective-C

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

@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 和 return nil 很容易,但我有很多这样的代码,它会不优雅且容易出错。

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

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

这是丑陋的样板文件(因此容易出错)。我宁愿有这样的东西:

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

但我想不出一种方法来为一般对象编写 ValidForNonNulls。

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

如果我必须验证许多这样的传入条款,并且我需要检查它们的有效性或 return 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,您可以对每个值进行更具体的测试。