YYModelにおけるint型プロパティのnull値受け入れ挙動

基本データ型(int/NSInteger)の挙動

@interface Employee : NSObject
@property (assign, nonatomic) int employeeId;
@property (assign, nonatomic) NSInteger serviceYears;
@end

// JSON: {"employeeId": null, "serviceYears": null}
Employee *emp = [Employee yy_modelWithJSON:json];
NSLog(@"%d", emp.employeeId);  // 出力: 0
NSLog(@"%ld", emp.serviceYears); // 出力: 0

結果: クラッシュせず、デフォルト値0が設定される

オブジェクト型(NSNumber)の挙動

@interface Employee : NSObject
@property (strong, nonatomic) NSNumber *employeeId;
@property (strong, nonatomic) NSNumber *serviceYears;
@end

// JSON: {"employeeId": null, "serviceYears": 5}
Employee *emp = [Employee yy_modelWithJSON:json];
NSLog(@"%@", emp.employeeId);  // 出力: (null)
NSLog(@"%@", emp.serviceYears); // 出力: 5

結果: クラッシュせず、null値はnilに変換される

安全な実装方法

方法1: NSNumberプロパティ + ヘルパーメソッド

@interface Employee : NSObject
@property (strong, nonatomic) NSNumber *employeeId;
@property (strong, nonatomic) NSNumber *serviceYears;

- (int)idAsInt;
- (NSInteger)serviceYearsAsInteger;
@end

@implementation Employee
- (int)idAsInt {
    return self.employeeId.intValue; // nilの場合は0を返す
}
- (NSInteger)serviceYearsAsInteger {
    return self.serviceYears.integerValue;
}
@end

方法2: カスタム変換ロジック

@implementation Employee
+ (NSDictionary *)modelCustomPropertyMapper {
    return @{@"employeeId": @"id"};
}

- (BOOL)modelCustomTransformFromDictionary:(NSDictionary *)dict {
    if ([dict[@"id"] isKindOfClass:NSNull.class]) {
        _employeeId = -999; // 特殊値を設定
    }
    return YES;
}
@end

方法3: 安全な辞書カテゴリ

@implementation NSDictionary (SafeAccess)
- (id)nullSafeObjectForKey:(NSString *)key {
    id obj = self[key];
    return (obj == NSNull.null) ? nil : obj;
}
@end

// モデル内での使用例
- (void)configureWithDict:(NSDictionary *)dict {
    NSNumber *idNum = [dict nullSafeObjectForKey:@"id"];
    _employeeId = idNum ? idNum.intValue : 0;
}

推奨アプローチ

@interface Employee : NSObject
@property (strong, nonatomic) NSNumber *employeeId;
@property (strong, nonatomic) NSNumber *serviceYears;

- (int32_t)idValueWithDefault:(int32_t)defaultValue;
@end

@implementation Employee
- (int32_t)idValueWithDefault:(int32_t)defaultValue {
    return self.employeeId ? self.employeeId.intValue : defaultValue;
}
@end

動作検証

NSDictionary *testData = @{@"id": [NSNull null], @"serviceYears": @5};
Employee *emp = [Employee yy_modelWithJSON:testData];
NSLog(@"%d", emp.employeeId); // 出力: 0(クラッシュなし)

総括

  • クラッシュ発生なし:YYModelはnull値を安全に処理
  • 基本データ型:null → 0 に自動変換
  • オブジェクト型:null → nil に変換
  • NSNumber使用が推奨:値の存在状態を明確に区別可能

タグ: YYModel iOS Objective-C JSON解析 Null安全

6月6日 19:12 投稿