KVCによるディクショナリのモデル化


プロジェクトでは、Jsonフィールドがモデルのカプセル化を要求する場合が一般的です.一般的には、モデルを構築し、Jsonが要求したモデル辞書の様々なフィールドがあります.name、ageのようなものです.とか.パッケージ化時に対応するモデル辞書を入手し,各フィールドの付与を行う動作はMVCのメカニズムに従い,一般的にモデルに入れて処理する.に似ている
-(void)toModelFromDictionary:(NSDictionary*)jsonDic{
self.name = jsonDic[@"name"];
self.age  = jsonDic[@"age"];
}

これにはいくつかの弊害があります.1、バックグラウンドで要求された辞書データは、NSNumber、Nsstringなど、さまざまなタイプの可能性があります.バックグラウンドのフィールドが空であれば、プログラムがクラッシュします.2、フィールドが多ければ、手書き辞書で模型を回すのは疲れる.
解決策は2つある:1.サードパーティのコントロールを使用して、李明傑先生のMJExtension、このコントロールは辞書の回転モデルを作ることができて、モデルの中でまたモデルを結ぶことができて、モデルの配列をつなぐことができて、機能は比較的に完備して強大です.機能点:JSON->Model、Core Data Model JSOnString->Model、Core Data Model、Core Data Model->JSON JSON Array->Model Array、Core Data Model Array JSOnString->Model Array、Core Data Model Array Model Array、Core Data Model Array Model Array、Core Data Model Model Model Array->JSON Array->JSON Array Coding all properties of model in line code.
https://github.com/CoderMJLee/MJExtension
  • サードパーティ製コントロールを使いたくない場合、自由度が低く制限されていると感じたら、KVCメカニズムを使用した次の方法
  • を試してみてください.
    - (void)setValuesForKeysWithDictionary:(NSDictionary *)keyedValues; 

    この関数ができることは、モデルの対応する属性をkeyedValuesの辞書キー値ペアに従ってコピーし、モデルの初歩的な変換を完了することです.ここでは、何も処理しなければ、モデルの属性タイプは辞書の値に対応しなければなりません.例えば、辞書の中のNSnumberのように、属性タイプもNSnumberでなければなりません.
    すべてのタイプを統一する方法はありますか?処理するのはそんなに面倒ではありません.タイプの対応をしなければなりませんか?モデルの中で以下の方法を実現することができて、システムは自動的に呼び出します
    //             
    -(void)setValue:(id)value forKey:(NSString *)key{
    
        if([value isKindOfClass:[NSNull class]]){
            value=nil;
        }else if([value isKindOfClass:[NSArray class]]){
        }else{
            value = [NSString stringWithFormat:@"%@",value];
        }
        [super setValue:value forKey:key];
    }
    
    //       id     
    -(void)setValue:(id)value forUndefinedKey:(NSString *)key{
        NSLog(@"Undefined Key: %@", key);
    }
    

    上記の2つの方法を実装するためにBaseModelをカプセル化し、次のような回転モデル方法を作成することができます.
    //      
    -(id)initWithDic:(NSDictionary *)modelDic{
    
        self = [super init];
        if(self){
            [self setValuesForKeysWithDictionary:modelDic];
        }
        return self;
    
    }

    使うときは大体こうです.
    EmployeModel *aEmploye = [[EmployeModel alloc]initWithDic:employeeDic]; 

    モデル内のモデルのネストや、モデル内のモデル配列や他の処理をしたい場合はどうすればいいですか?EmployeModelの中でBaseModelの中のsetValueForKeyを複写します.例えば、私のEmployeModelの中にはtimesの辞書の配列があります.配列の中にはモデルがあり、単独で処理します.それ以外に、他のデータの微調整処理もできます.
    - (void)setValue:(id)value forKey:(NSString *)key{
    
    //               -
        if ([key isEqualToString:@"mobile"]) {
            NSArray *arr = [(NSString *)value componentsSeparatedByString:@"-"];
            value = [arr componentsJoinedByString:@""];
        }else if([key isEqualToString:@"times"]){
    
            NSMutableArray *retArr = [NSMutableArray array];
    
            for (int i=0; i<((NSArray *)value).count; i++) {
    
                NSDictionary * aDayTimeDic = ((NSArray *)value)[i];
                TimeModel *aDayTime = [[TimeModel alloc]initWithDic:aDayTimeDic];
                [retArr addObject:aDayTime];
    
            }
            value = retArr;
        }
        [super setValue:value forKey:key];
    }