zoukankan      html  css  js  c++  java
  • YYModel 源码解读(二)之NSObject+YYModel.h (5)

    好了,之前的博文中详细的解释了一些辅助的类和辅助的函数,接下来就是使用它们来实现酷炫功能的时候,正所谓磨刀不误砍柴工啊

    我们先把总的功能罗列出来

    1. json转字典              + (NSDictionary *)_yy_dictionaryWithJSON:(id)json

    2. json转模型              + (instancetype)yy_modelWithJSON:(id)json

    3. 字典转模型              + (instancetype)yy_modelWithDictionary:(NSDictionary *)dictionary

    4. 模型转json               - (id)yy_modelToJSONObject

    5. 模型转NSData          - (NSData *)yy_modelToJSONData

    6. 模型转json字符串      - (NSString *)yy_modelToJSONString

    7. 模型copy                 - (id)yy_modelCopy

    8. 模型归档解档            - (id)yy_modelInitWithCoder:(NSCoder *)aDecoder  /   - (void)yy_modelEncodeWithCoder:(NSCoder *)aCoder

    9. 模型hash值              - (NSUInteger)yy_modelHash

    10. 模型是否相等           - (BOOL)yy_modelIsEqual:(id)model 

    11. 模型描述                 - (NSString *)yy_modelDescription

    功能我们已经清楚了 下边我们看看具体的实现

    1.

     1 /**
     2  *  把id类型的数据转换成字典
     3  *
     4  *  @param json 这个id类型为 NSDictionary / NSString / NSData
     5  *
     6  *  @return 字典 / 可能为空
     7  */
     8 + (NSDictionary *)_yy_dictionaryWithJSON:(id)json {
     9     
    10     // 判空处理
    11     if (!json || json == (id)kCFNull) return nil;
    12     
    13     // 定义返回的数据 和把json转为NSData的临时变量
    14     NSDictionary *dic = nil;
    15     NSData *jsonData = nil;
    16     
    17     // 字典 直接赋值
    18     if ([json isKindOfClass:[NSDictionary class]]) {
    19         dic = json;
    20         
    21         // 字符串 转成NSData
    22     } else if ([json isKindOfClass:[NSString class]]) {
    23         jsonData = [(NSString *)json dataUsingEncoding : NSUTF8StringEncoding];
    24         
    25         // NSData 直接赋值
    26     } else if ([json isKindOfClass:[NSData class]]) {
    27         jsonData = json;
    28     }
    29     
    30     // 把NSData 转为 字典
    31     if (jsonData) {
    32         dic = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:NULL];
    33         if (![dic isKindOfClass:[NSDictionary class]]) dic = nil;
    34     }
    35     return dic;
    36 }

    2.

     1 /**
     2  *  json转模型
     3  *
     4  *  @param json json 这个id类型为 NSDictionary / NSString / NSData
     5  *
     6  *  @return 模型 / 可能为空
     7  */
     8 + (instancetype)yy_modelWithJSON:(id)json {
     9     
    10     // 先把json转为字典
    11     NSDictionary *dic = [self _yy_dictionaryWithJSON:json];
    12     
    13     // 调用yy_modelWithDictionary函数把字典转换成模型
    14     return [self yy_modelWithDictionary:dic];
    15 }

    3.

     1 /**
     2  *  字典转模型
     3  *
     4  *  @param dictionary 字典
     5  *
     6  *  @return 模型 / 可能为空
     7  */
     8 + (instancetype)yy_modelWithDictionary:(NSDictionary *)dictionary {
     9     
    10     // 判空 / 判断类型
    11     if (!dictionary || dictionary == (id)kCFNull) return nil;
    12     if (![dictionary isKindOfClass:[NSDictionary class]]) return nil;
    13     
    14     // 获取自身的类型
    15     Class cls = [self class];
    16     
    17     // 新建一个model抽象类
    18     _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:cls];
    19     
    20     // 判断有没有自定义返回类型,有就返回自定义的类型
    21     if (modelMeta->_hasCustomClassFromDictionary) {
    22         cls = [cls modelCustomClassForDictionary:dictionary] ?: cls;
    23     }
    24     
    25     // 创建一个该类的实例对象
    26     NSObject *one = [cls new];
    27     
    28     // 调用yy_modelSetWithDictionary方法给新建的对象赋值
    29     if ([one yy_modelSetWithDictionary:dictionary]) return one;
    30     return nil;
    31 }
     1 /**
     2  *  辅助赋值函数
     3  *
     4  *  @param json json 这个id类型为 NSDictionary / NSString / NSData
     5  *
     6  *  @return 模型 / 可能为空
     7  */
     8 - (BOOL)yy_modelSetWithJSON:(id)json {
     9     
    10     // 先转字典
    11     NSDictionary *dic = [NSObject _yy_dictionaryWithJSON:json];
    12     
    13     // 调用yy_modelSetWithDictionary函数赋值并返回对象
    14     return [self yy_modelSetWithDictionary:dic];
    15 }
     1 /**
     2  *  通过字典给模型对象赋值
     3  *
     4  *  @param dic 字典
     5  *
     6  *  @return 赋值是否成功
     7  */
     8 - (BOOL)yy_modelSetWithDictionary:(NSDictionary *)dic {
     9     
    10     
    11     
    12     // 判空 / 判断类型
    13     if (!dic || dic == (id)kCFNull) return NO;
    14     if (![dic isKindOfClass:[NSDictionary class]]) return NO;
    15     
    16     // 新建一个model抽象类
    17     _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:object_getClass(self)];
    18     // 没有可映射的属性就返回NO
    19     if (modelMeta->_keyMappedCount == 0) return NO;
    20     
    21     
    22     // 这里添加了一个判断,如果用户写了NO 就没必要走下边的代码了
    23     if (!modelMeta->_hasCustomTransformFromDictionary) {
    24         return NO;
    25     }
    26     
    27     // 如果对字典做过自定义的描述,对字典做进一步的处理
    28     if (modelMeta->_hasCustomWillTransformFromDictionary) {
    29         dic = [((id<YYModel>)self) modelCustomWillTransformFromDictionary:dic];
    30         if (![dic isKindOfClass:[NSDictionary class]]) return NO;
    31     }
    32     
    33     // 创建ModelSetContext结构体
    34     ModelSetContext context = {0};
    35     context.modelMeta = (__bridge void *)(modelMeta);
    36     context.model = (__bridge void *)(self);
    37     context.dictionary = (__bridge void *)(dic);
    38     
    39     // 如果模型中的属性个数大于字典的个数,以字典为主
    40     if (modelMeta->_keyMappedCount >= CFDictionaryGetCount((CFDictionaryRef)dic)) {
    41         
    42         //CFDictionaryApplyFunction
    43         CFDictionaryApplyFunction((CFDictionaryRef)dic, ModelSetWithDictionaryFunction, &context);
    44         
    45         // _keyPathPropertyMetas
    46         if (modelMeta->_keyPathPropertyMetas) {
    47             CFArrayApplyFunction((CFArrayRef)modelMeta->_keyPathPropertyMetas,
    48                                  CFRangeMake(0, CFArrayGetCount((CFArrayRef)modelMeta->_keyPathPropertyMetas)),
    49                                  ModelSetWithPropertyMetaArrayFunction,
    50                                  &context);
    51         }
    52         
    53         // _multiKeysPropertyMetas
    54         if (modelMeta->_multiKeysPropertyMetas) {
    55             CFArrayApplyFunction((CFArrayRef)modelMeta->_multiKeysPropertyMetas,
    56                                  CFRangeMake(0, CFArrayGetCount((CFArrayRef)modelMeta->_multiKeysPropertyMetas)),
    57                                  ModelSetWithPropertyMetaArrayFunction,
    58                                  &context);
    59         }
    60     } else {
    61         CFArrayApplyFunction((CFArrayRef)modelMeta->_allPropertyMetas,
    62                              CFRangeMake(0, modelMeta->_keyMappedCount),
    63                              ModelSetWithPropertyMetaArrayFunction,
    64                              &context);
    65     }
    66     
    67     // 通过自定义的modelCustomTransformFromDictionary方法来确定是否要转模型
    68     if (modelMeta->_hasCustomTransformFromDictionary) {
    69         return [((id<YYModel>)self) modelCustomTransformFromDictionary:dic];
    70     }
    71     
    72     return YES;
    73 }

    4.

     1 /**
     2  *  模型转json对象
     3  *
     4  *  @return 返回字典或者数组 / 可能为空
     5  */
     6 - (id)yy_modelToJSONObject {
     7     /*
     8      Apple said:
     9      The top level object is an NSArray or NSDictionary.
    10      All objects are instances of NSString, NSNumber, NSArray, NSDictionary, or NSNull.
    11      All dictionary keys are instances of NSString.
    12      Numbers are not NaN or infinity.
    13      */
    14     
    15     // 使用ModelToJSONObjectRecursive转换不合法的转json数据
    16     id jsonObject = ModelToJSONObjectRecursive(self);
    17     if ([jsonObject isKindOfClass:[NSArray class]]) return jsonObject;
    18     if ([jsonObject isKindOfClass:[NSDictionary class]]) return jsonObject;
    19     return nil;
    20 }

    5.

     1 /**
     2  *  模型转jsonData
     3  *
     4  *  @return NSData
     5  */
     6 - (NSData *)yy_modelToJSONData {
     7     id jsonObject = [self yy_modelToJSONObject];
     8     if (!jsonObject) return nil;
     9     return [NSJSONSerialization dataWithJSONObject:jsonObject options:0 error:NULL];
    10 }

    6.

    1 - (NSString *)yy_modelToJSONString {
    2     NSData *jsonData = [self yy_modelToJSONData];
    3     if (jsonData.length == 0) return nil;
    4     return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    5 }

    7.

     1 /**
     2  *  对原有模型的copy
     3  *
     4  *  @return 生成一个新的或者本身对象
     5  */
     6 - (id)yy_modelCopy{
     7     
     8     // kCFNull 就返回自身
     9     if (self == (id)kCFNull) return self;
    10     
    11     // 新建一个model抽象类
    12     _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:self.class];
    13     
    14     // 如果是ns类型 直接返回自身的copy对象
    15     if (modelMeta->_nsType) return [self copy];
    16     
    17     // 新建一个自身对象,然后便利所有的属性
    18     NSObject *one = [self.class new];
    19     for (_YYModelPropertyMeta *propertyMeta in modelMeta->_allPropertyMetas) {
    20         
    21         // 略去没有setter 或者 getter 方法的属性
    22         if (!propertyMeta->_getter || !propertyMeta->_setter) continue;
    23         
    24         // 处理属性为c的情况
    25         if (propertyMeta->_isCNumber) {
    26             switch (propertyMeta->_type & YYEncodingTypeMask) {
    27                 case YYEncodingTypeBool: {
    28                     bool num = ((bool (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter);
    29                     ((void (*)(id, SEL, bool))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num);
    30                 } break;
    31                 case YYEncodingTypeInt8:
    32                 case YYEncodingTypeUInt8: {
    33                     uint8_t num = ((bool (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter);
    34                     ((void (*)(id, SEL, uint8_t))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num);
    35                 } break;
    36                 case YYEncodingTypeInt16:
    37                 case YYEncodingTypeUInt16: {
    38                     uint16_t num = ((uint16_t (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter);
    39                     ((void (*)(id, SEL, uint16_t))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num);
    40                 } break;
    41                 case YYEncodingTypeInt32:
    42                 case YYEncodingTypeUInt32: {
    43                     uint32_t num = ((uint32_t (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter);
    44                     ((void (*)(id, SEL, uint32_t))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num);
    45                 } break;
    46                 case YYEncodingTypeInt64:
    47                 case YYEncodingTypeUInt64: {
    48                     uint64_t num = ((uint64_t (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter);
    49                     ((void (*)(id, SEL, uint64_t))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num);
    50                 } break;
    51                 case YYEncodingTypeFloat: {
    52                     float num = ((float (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter);
    53                     ((void (*)(id, SEL, float))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num);
    54                 } break;
    55                 case YYEncodingTypeDouble: {
    56                     double num = ((double (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter);
    57                     ((void (*)(id, SEL, double))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num);
    58                 } break;
    59                 case YYEncodingTypeLongDouble: {
    60                     long double num = ((long double (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter);
    61                     ((void (*)(id, SEL, long double))(void *) objc_msgSend)((id)one, propertyMeta->_setter, num);
    62                 } // break; commented for code coverage in next line
    63                 default: break;
    64             }
    65         } else {
    66             switch (propertyMeta->_type & YYEncodingTypeMask) {
    67                 case YYEncodingTypeObject:
    68                 case YYEncodingTypeClass:
    69                 case YYEncodingTypeBlock: {
    70                     id value = ((id (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter);
    71                     ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)one, propertyMeta->_setter, value);
    72                 } break;
    73                     
    74                     // 特别之处这里获取的是指针,之所以使用size_t 是考虑到平台方面的东西
    75                 case YYEncodingTypeSEL:
    76                 case YYEncodingTypePointer:
    77                 case YYEncodingTypeCString: {
    78                     size_t value = ((size_t (*)(id, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_getter);
    79                     ((void (*)(id, SEL, size_t))(void *) objc_msgSend)((id)one, propertyMeta->_setter, value);
    80                 } break;
    81                 case YYEncodingTypeStruct:
    82                 case YYEncodingTypeUnion: {
    83                     @try {
    84                         NSValue *value = [self valueForKey:NSStringFromSelector(propertyMeta->_getter)];
    85                         if (value) {
    86                             [one setValue:value forKey:propertyMeta->_name];
    87                         }
    88                     } @catch (NSException *exception) {}
    89                 } // break; commented for code coverage in next line
    90                 default: break;
    91             }
    92         }
    93     }
    94     return one;
    95 }

    8.

      1 - (void)yy_modelEncodeWithCoder:(NSCoder *)aCoder {
      2     if (!aCoder) return;
      3     if (self == (id)kCFNull) {
      4         [((id<NSCoding>)self)encodeWithCoder:aCoder];
      5         return;
      6     }
      7     
      8     _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:self.class];
      9     if (modelMeta->_nsType) {
     10         [((id<NSCoding>)self)encodeWithCoder:aCoder];
     11         return;
     12     }
     13     
     14     for (_YYModelPropertyMeta *propertyMeta in modelMeta->_allPropertyMetas) {
     15         if (!propertyMeta->_getter) return;
     16         
     17         if (propertyMeta->_isCNumber) {
     18             NSNumber *value = ModelCreateNumberFromProperty(self, propertyMeta);
     19             if (value) [aCoder encodeObject:value forKey:propertyMeta->_name];
     20         } else {
     21             switch (propertyMeta->_type & YYEncodingTypeMask) {
     22                 case YYEncodingTypeObject: {
     23                     id value = ((id (*)(id, SEL))(void *)objc_msgSend)((id)self, propertyMeta->_getter);
     24                     if (value && (propertyMeta->_nsType || [value respondsToSelector:@selector(encodeWithCoder:)])) {
     25                         if ([value isKindOfClass:[NSValue class]]) {
     26                             if ([value isKindOfClass:[NSNumber class]]) {
     27                                 [aCoder encodeObject:value forKey:propertyMeta->_name];
     28                             }
     29                         } else {
     30                             [aCoder encodeObject:value forKey:propertyMeta->_name];
     31                         }
     32                     }
     33                 } break;
     34                 case YYEncodingTypeSEL: {
     35                     SEL value = ((SEL (*)(id, SEL))(void *)objc_msgSend)((id)self, propertyMeta->_getter);
     36                     if (value) {
     37                         NSString *str = NSStringFromSelector(value);
     38                         [aCoder encodeObject:str forKey:propertyMeta->_name];
     39                     }
     40                 } break;
     41                 case YYEncodingTypeStruct:
     42                 case YYEncodingTypeUnion: {
     43                     if (propertyMeta->_isKVCCompatible && propertyMeta->_isStructAvailableForKeyedArchiver) {
     44                         @try {
     45                             NSValue *value = [self valueForKey:NSStringFromSelector(propertyMeta->_getter)];
     46                             [aCoder encodeObject:value forKey:propertyMeta->_name];
     47                         } @catch (NSException *exception) {}
     48                     }
     49                 } break;
     50                     
     51                 default:
     52                     break;
     53             }
     54         }
     55     }
     56 }
     57 
     58 - (id)yy_modelInitWithCoder:(NSCoder *)aDecoder {
     59     if (!aDecoder) return self;
     60     if (self == (id)kCFNull) return self;    
     61     _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:self.class];
     62     if (modelMeta->_nsType) return self;
     63     
     64     for (_YYModelPropertyMeta *propertyMeta in modelMeta->_allPropertyMetas) {
     65         if (!propertyMeta->_setter) continue;
     66         
     67         if (propertyMeta->_isCNumber) {
     68             NSNumber *value = [aDecoder decodeObjectForKey:propertyMeta->_name];
     69             if ([value isKindOfClass:[NSNumber class]]) {
     70                 ModelSetNumberToProperty(self, value, propertyMeta);
     71                 [value class];
     72             }
     73         } else {
     74             YYEncodingType type = propertyMeta->_type & YYEncodingTypeMask;
     75             switch (type) {
     76                 case YYEncodingTypeObject: {
     77                     id value = [aDecoder decodeObjectForKey:propertyMeta->_name];
     78                     ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)self, propertyMeta->_setter, value);
     79                 } break;
     80                 case YYEncodingTypeSEL: {
     81                     NSString *str = [aDecoder decodeObjectForKey:propertyMeta->_name];
     82                     if ([str isKindOfClass:[NSString class]]) {
     83                         SEL sel = NSSelectorFromString(str);
     84                         ((void (*)(id, SEL, SEL))(void *) objc_msgSend)((id)self, propertyMeta->_setter, sel);
     85                     }
     86                 } break;
     87                 case YYEncodingTypeStruct:
     88                 case YYEncodingTypeUnion: {
     89                     if (propertyMeta->_isKVCCompatible) {
     90                         @try {
     91                             NSValue *value = [aDecoder decodeObjectForKey:propertyMeta->_name];
     92                             if (value) [self setValue:value forKey:propertyMeta->_name];
     93                         } @catch (NSException *exception) {}
     94                     }
     95                 } break;
     96                     
     97                 default:
     98                     break;
     99             }
    100         }
    101     }
    102     return self;
    103 }

    9.

     1 - (NSUInteger)yy_modelHash {
     2     if (self == (id)kCFNull) return [self hash];
     3     _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:self.class];
     4     if (modelMeta->_nsType) return [self hash];
     5     
     6     NSUInteger value = 0;
     7     NSUInteger count = 0;
     8     for (_YYModelPropertyMeta *propertyMeta in modelMeta->_allPropertyMetas) {
     9         if (!propertyMeta->_isKVCCompatible) continue;
    10         value ^= [[self valueForKey:NSStringFromSelector(propertyMeta->_getter)] hash];
    11         count++;
    12     }
    13     if (count == 0) value = (long)((__bridge void *)self);
    14     return value;
    15 }

    10.

     1 /**
     2  *  比较是否相等
     3  *  比较的规则是:
     4  1. 直接使用==比较 相同则返回YES
     5  2. 使用isMemberOfClass方法,
     6  3. 如果是nsType 使用isEqual 比较
     7  4. 使用hash比较
     8  5. 便利模型中的全部属性,判断是否支持KVC 在判断属性是否完全相等
     9  */
    10 - (BOOL)yy_modelIsEqual:(id)model {
    11     if (self == model) return YES;
    12     if (![model isMemberOfClass:self.class]) return NO;
    13     _YYModelMeta *modelMeta = [_YYModelMeta metaWithClass:self.class];
    14     if (modelMeta->_nsType) return [self isEqual:model];
    15     if ([self hash] != [model hash]) return NO;
    16     
    17     for (_YYModelPropertyMeta *propertyMeta in modelMeta->_allPropertyMetas) {
    18         if (!propertyMeta->_isKVCCompatible) continue;
    19         id this = [self valueForKey:NSStringFromSelector(propertyMeta->_getter)];
    20         id that = [model valueForKey:NSStringFromSelector(propertyMeta->_getter)];
    21         if (this == that) continue;
    22         if (this == nil || that == nil) return NO;
    23         if (![this isEqual:that]) return NO;
    24     }
    25     return YES;
    26 }

    11.

    1 - (NSString *)yy_modelDescription {
    2     return ModelDescription(self);
    3 }

    下边的是一些对NSArray / NSDictionary 的分类

    把json 转为 NSArray 里边装着cls类型的转好模型的数据

     1 @implementation NSArray (YYModel)
     2 
     3 + (NSArray *)yy_modelArrayWithClass:(Class)cls json:(id)json {
     4     if (!json) return nil;
     5     NSArray *arr = nil;
     6     NSData *jsonData = nil;
     7     if ([json isKindOfClass:[NSArray class]]) {
     8         arr = json;
     9     } else if ([json isKindOfClass:[NSString class]]) {
    10         jsonData = [(NSString *)json dataUsingEncoding : NSUTF8StringEncoding];
    11     } else if ([json isKindOfClass:[NSData class]]) {
    12         jsonData = json;
    13     }
    14     if (jsonData) {
    15         arr = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:NULL];
    16         if (![arr isKindOfClass:[NSArray class]]) arr = nil;
    17     }
    18     return [self yy_modelArrayWithClass:cls array:arr];
    19 }
    20 
    21 + (NSArray *)yy_modelArrayWithClass:(Class)cls array:(NSArray *)arr {
    22     if (!cls || !arr) return nil;
    23     NSMutableArray *result = [NSMutableArray new];
    24     for (NSDictionary *dic in arr) {
    25         if (![dic isKindOfClass:[NSDictionary class]]) continue;
    26         NSObject *obj = [cls yy_modelWithDictionary:dic];
    27         if (obj) [result addObject:obj];
    28     }
    29     return result;
    30 }
    31 
    32 @end

    把字典中的value转为cls模型后使用字典的key保存为一个新的字典后返回

     1 @implementation NSDictionary (YYModel)
     2 
     3 + (NSDictionary *)yy_modelDictionaryWithClass:(Class)cls json:(id)json {
     4     if (!json) return nil;
     5     NSDictionary *dic = nil;
     6     NSData *jsonData = nil;
     7     if ([json isKindOfClass:[NSDictionary class]]) {
     8         dic = json;
     9     } else if ([json isKindOfClass:[NSString class]]) {
    10         jsonData = [(NSString *)json dataUsingEncoding : NSUTF8StringEncoding];
    11     } else if ([json isKindOfClass:[NSData class]]) {
    12         jsonData = json;
    13     }
    14     if (jsonData) {
    15         dic = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:NULL];
    16         if (![dic isKindOfClass:[NSDictionary class]]) dic = nil;
    17     }
    18     return [self yy_modelDictionaryWithClass:cls dictionary:dic];
    19 }
    20 
    21 + (NSDictionary *)yy_modelDictionaryWithClass:(Class)cls dictionary:(NSDictionary *)dic {
    22     if (!cls || !dic) return nil;
    23     NSMutableDictionary *result = [NSMutableDictionary new];
    24     for (NSString *key in dic.allKeys) {
    25         if (![key isKindOfClass:[NSString class]]) continue;
    26         NSObject *obj = [cls yy_modelWithDictionary:dic[key]];
    27         if (obj) result[key] = obj;
    28     }
    29     return result;
    30 }
    31 
    32 @end
  • 相关阅读:
    IPC总结学习
    机器学习中的范数规则
    机器学习的几个误区-转载
    来几道大数据的面试题吧
    海量数据随机抽样问题(蓄水池问题)
    字符串类算法题目总结
    RPC学习
    如何做出健壮的系统设计
    关于bind函数和connect函数的测试结论
    [置顶] Codeforces Round #197 (Div. 2)(完全)
  • 原文地址:https://www.cnblogs.com/machao/p/5635397.html
Copyright © 2011-2022 走看看