基本データ型(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使用が推奨:値の存在状態を明確に区別可能