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

    本篇主要介绍的是 在真正转之前的几个辅助函数

    /**
     Get number from property.
     @discussion Caller should hold strong reference to the parameters before this function returns.
     @param model Should not be nil.
     @param meta  Should not be nil, meta.isCNumber should be YES, meta.getter should not be nil.
     @return A number object, or nil if failed.
     */
    static force_inline NSNumber *ModelCreateNumberFromProperty(__unsafe_unretained id model,
                                                                __unsafe_unretained _YYModelPropertyMeta *meta) {
        switch (meta->_type & YYEncodingTypeMask) {
            case YYEncodingTypeBool: {
                return @(((bool (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter));
            }
            case YYEncodingTypeInt8: {
                
                return @(((int8_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter));
            }
            case YYEncodingTypeUInt8: {
                return @(((uint8_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter));
            }
            case YYEncodingTypeInt16: {
                return @(((int16_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter));
            }
            case YYEncodingTypeUInt16: {
                return @(((uint16_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter));
            }
            case YYEncodingTypeInt32: {
                return @(((int32_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter));
            }
            case YYEncodingTypeUInt32: {
                return @(((uint32_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter));
            }
            case YYEncodingTypeInt64: {
                return @(((int64_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter));
            }
            case YYEncodingTypeUInt64: {
                return @(((uint64_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter));
            }
            case YYEncodingTypeFloat: {
                float num = ((float (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter);
                if (isnan(num) || isinf(num)) return nil;
                return @(num);
            }
            case YYEncodingTypeDouble: {
                double num = ((double (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter);
                if (isnan(num) || isinf(num)) return nil;
                return @(num);
            }
            case YYEncodingTypeLongDouble: {
                double num = ((long double (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter);
                if (isnan(num) || isinf(num)) return nil;
                return @(num);
            }
            default: return nil;
        }
    }

    这个函数的目的 是 把 _YYModelPropertyMeta.isCNumber == YES  的情况转成NSNumber  

    // 像这样的类型是C 的 需要调用上边的函数进行转换
    @property (nonatomic, assign) int32_t blockWord;
    ((int8_t (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter)

    这个方法 是 类似[obj method]; 这中方法调用的Runtime 内部实现 根据方法的返回值不同获取不同的返回类型
    ((Class (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter)

    下边这个方法是 把 NSNumber 赋值给 原有c 属性

    /**
     Set number to property.
     @discussion Caller should hold strong reference to the parameters before this function returns.
     @param model Should not be nil.
     @param num   Can be nil.
     @param meta  Should not be nil, meta.isCNumber should be YES, meta.setter should not be nil.
     */
    static force_inline void ModelSetNumberToProperty(__unsafe_unretained id model,
                                                      __unsafe_unretained NSNumber *num,
                                                      __unsafe_unretained _YYModelPropertyMeta *meta) {
        switch (meta->_type & YYEncodingTypeMask) {
            case YYEncodingTypeBool: {
                ((void (*)(id, SEL, bool))(void *) objc_msgSend)((id)model, meta->_setter, num.boolValue);
            } break;
            case YYEncodingTypeInt8: {
                ((void (*)(id, SEL, int8_t))(void *) objc_msgSend)((id)model, meta->_setter, (int8_t)num.charValue);
            } break;
            case YYEncodingTypeUInt8: {
                ((void (*)(id, SEL, uint8_t))(void *) objc_msgSend)((id)model, meta->_setter, (uint8_t)num.unsignedCharValue);
            } break;
            case YYEncodingTypeInt16: {
                ((void (*)(id, SEL, int16_t))(void *) objc_msgSend)((id)model, meta->_setter, (int16_t)num.shortValue);
            } break;
            case YYEncodingTypeUInt16: {
                ((void (*)(id, SEL, uint16_t))(void *) objc_msgSend)((id)model, meta->_setter, (uint16_t)num.unsignedShortValue);
            } break;
            case YYEncodingTypeInt32: {
                ((void (*)(id, SEL, int32_t))(void *) objc_msgSend)((id)model, meta->_setter, (int32_t)num.intValue);
            }
            case YYEncodingTypeUInt32: {
                ((void (*)(id, SEL, uint32_t))(void *) objc_msgSend)((id)model, meta->_setter, (uint32_t)num.unsignedIntValue);
            } break;
            case YYEncodingTypeInt64: {
                if ([num isKindOfClass:[NSDecimalNumber class]]) {
                    ((void (*)(id, SEL, int64_t))(void *) objc_msgSend)((id)model, meta->_setter, (int64_t)num.stringValue.longLongValue);
                } else {
                    ((void (*)(id, SEL, uint64_t))(void *) objc_msgSend)((id)model, meta->_setter, (uint64_t)num.longLongValue);
                }
            } break;
            case YYEncodingTypeUInt64: {
                if ([num isKindOfClass:[NSDecimalNumber class]]) {
                    ((void (*)(id, SEL, int64_t))(void *) objc_msgSend)((id)model, meta->_setter, (int64_t)num.stringValue.longLongValue);
                } else {
                    ((void (*)(id, SEL, uint64_t))(void *) objc_msgSend)((id)model, meta->_setter, (uint64_t)num.unsignedLongLongValue);
                }
            } break;
            case YYEncodingTypeFloat: {
                float f = num.floatValue;
                if (isnan(f) || isinf(f)) f = 0;
                ((void (*)(id, SEL, float))(void *) objc_msgSend)((id)model, meta->_setter, f);
            } break;
            case YYEncodingTypeDouble: {
                double d = num.doubleValue;
                if (isnan(d) || isinf(d)) d = 0;
                ((void (*)(id, SEL, double))(void *) objc_msgSend)((id)model, meta->_setter, d);
            } break;
            case YYEncodingTypeLongDouble: {
                long double d = num.doubleValue;
                if (isnan(d) || isinf(d)) d = 0;
                ((void (*)(id, SEL, long double))(void *) objc_msgSend)((id)model, meta->_setter, (long double)d);
            } // break; commented for code coverage in next line
            default: break;
        }
    }
    //  这个相对于上边的那个Runtime 方法  多了一个参数
    ((void (*)(id, SEL, bool))(void *) objc_msgSend)((id)model, meta->_setter, num.boolValue);

    ((void (*)(id, SEL, 参数))(void *) objc_msgSend)((id)model, meta->_setter, 参数值);

    下边的这个方法是核心方法, 把值 赋值给model  需要的参数 有3 个 

    1. 需要被复制的Model 

    2. 值

    3. 需要把值赋值给谁

    数据类型主要分三种情况,根据 _PropertyMeta对象记录的类型

    • propertyMeta->_isCNumber,基本数值类型
      • bool
      • int8/uint8
      • int16/uint16
      • int32/uint32
      • int64/uint64
      • float
      • double
      • long double
    • propertyMeta->_foundationType,Foundation Class
      • NSString
      • NSArray
      • NSSet
      • NSDictionary
      • NSNumber
      • NSDecimalNumber
      • NSValue
      • NSData
      • NSDate
      • NSURL
    • propertyMeta->_encodingType & XZHEncodingTypeIvarMask,属性变量类型其他类型
      • 自定义NSObject实体类
      • Class
      • SEL
      • Block
      • Struct/Union
      • c数组
      • c字符串
      • c指针

     下边的这个方法是吧value 赋值给相应的Property 需要根据property的类型 进行各种判断, 需要注意的是当用户实现了 下边的这个方法

    + (Class)modelCustomClassForDictionary:(NSDictionary*)dictionary {
                if (dictionary[@"radius"] != nil) {
                    return [YYCircle class];
                } else if (dictionary[@"width"] != nil) {
                    return [YYRectangle class];
                } else if (dictionary[@"y2"] != nil) {
                    return [YYLine class];
                } else {
                    return [self class];
                }
            }

    这个方法是让用户自己制定 字典内部的返回值类型,如果制定了,在字典转模型的时候,就会按照这个制定的类型进行转换

      1 /**
      2  Set value to model with a property meta.
      3  
      4  @discussion Caller should hold strong reference to the parameters before this function returns.
      5  
      6  @param model Should not be nil.
      7  @param value Should not be nil, but can be NSNull.
      8  @param meta  Should not be nil, and meta->_setter should not be nil.
      9  */
     10 static void ModelSetValueForProperty(__unsafe_unretained id model,
     11                                      __unsafe_unretained id value,
     12                                      __unsafe_unretained _YYModelPropertyMeta *meta) {
     13     
     14     /**
     15      *  先判断 是不是c 类型的数据
     16      */
     17     if (meta->_isCNumber) {
     18         
     19         /**
     20          *    把 值 转换成 NSnumber
     21          */
     22         NSNumber *num = YYNSNumberCreateFromID(value);
     23         
     24         //  设置到 Property 中
     25         ModelSetNumberToProperty(model, num, meta);
     26         
     27         //  这个不知道是什么意思
     28         if (num) [num class]; // hold the number
     29         
     30     }
     31     // Foundation 类型
     32     else if (meta->_nsType) {
     33         
     34         // 如果是kCFNull 就赋值为(id)nil
     35         if (value == (id)kCFNull) {
     36             ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, (id)nil);
     37         } else {
     38             
     39             // 按照不同的Foundation 类型会有不同的赋值方式
     40             switch (meta->_nsType) {
     41                 case YYEncodingTypeNSString:
     42                 case YYEncodingTypeNSMutableString: {
     43                     
     44                     // value 是字符串或者可变字符串
     45                     if ([value isKindOfClass:[NSString class]]) {
     46                         if (meta->_nsType == YYEncodingTypeNSString) {
     47                             ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
     48                         } else {
     49                             ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, ((NSString *)value).mutableCopy);
     50                         }
     51                     }
     52                     
     53                     // value 是 NSNumber 需要根据是不是 可变的进行不同的赋值
     54                     else if ([value isKindOfClass:[NSNumber class]]) {
     55                         ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model,
     56                                                                        meta->_setter,
     57                                                                        (meta->_nsType == YYEncodingTypeNSString) ?
     58                                                                        ((NSNumber *)value).stringValue :
     59                                                                        ((NSNumber *)value).stringValue.mutableCopy);
     60                     }
     61                      // value 是NSData
     62                     else if ([value isKindOfClass:[NSData class]]) {
     63                         NSMutableString *string = [[NSMutableString alloc] initWithData:value encoding:NSUTF8StringEncoding];
     64                         ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, string);
     65                     }
     66                     
     67                     // value 是NSURL
     68                     else if ([value isKindOfClass:[NSURL class]]) {
     69                         ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model,
     70                                                                        meta->_setter,
     71                                                                        (meta->_nsType == YYEncodingTypeNSString) ?
     72                                                                        ((NSURL *)value).absoluteString :
     73                                                                        ((NSURL *)value).absoluteString.mutableCopy);
     74                     }
     75                     // value 是带属性的字符串
     76                     else if ([value isKindOfClass:[NSAttributedString class]]) {
     77                         ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model,
     78                                                                        meta->_setter,
     79                                                                        (meta->_nsType == YYEncodingTypeNSString) ?
     80                                                                        ((NSAttributedString *)value).string :
     81                                                                        ((NSAttributedString *)value).string.mutableCopy);
     82                     }
     83                 } break;
     84                     
     85                 case YYEncodingTypeNSValue:
     86                 case YYEncodingTypeNSNumber:
     87                 case YYEncodingTypeNSDecimalNumber: {
     88                     if (meta->_nsType == YYEncodingTypeNSNumber) {
     89                         ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, YYNSNumberCreateFromID(value));
     90                     }
     91                     
     92                     // 科学计数值 这里判断了3种情况,需要更具不同的情况转化为NSDecimalNumber
     93                     else if (meta->_nsType == YYEncodingTypeNSDecimalNumber) {
     94                         if ([value isKindOfClass:[NSDecimalNumber class]]) {
     95                             ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
     96                         } else if ([value isKindOfClass:[NSNumber class]]) {
     97                             NSDecimalNumber *decNum = [NSDecimalNumber decimalNumberWithDecimal:[((NSNumber *)value) decimalValue]];
     98                             ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, decNum);
     99                         } else if ([value isKindOfClass:[NSString class]]) {
    100                             NSDecimalNumber *decNum = [NSDecimalNumber decimalNumberWithString:value];
    101                             NSDecimal dec = decNum.decimalValue;
    102                             if (dec._length == 0 && dec._isNegative) {
    103                                 decNum = nil; // NaN
    104                             }
    105                             ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, decNum);
    106                         }
    107                     } else { // YYEncodingTypeNSValue
    108                         if ([value isKindOfClass:[NSValue class]]) {
    109                             ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
    110                         }
    111                     }
    112                 } break;
    113                     
    114                 // 一般NSData 有两种标示,一种是NSData 一种是NSString ,但最终都需要转换成NSData或者NSMutableData
    115                 case YYEncodingTypeNSData:
    116                 case YYEncodingTypeNSMutableData: {
    117                     if ([value isKindOfClass:[NSData class]]) {
    118                         if (meta->_nsType == YYEncodingTypeNSData) {
    119                             ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
    120                         } else {
    121                             NSMutableData *data = ((NSData *)value).mutableCopy;
    122                             ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, data);
    123                         }
    124                     } else if ([value isKindOfClass:[NSString class]]) {
    125                         NSData *data = [(NSString *)value dataUsingEncoding:NSUTF8StringEncoding];
    126                         if (meta->_nsType == YYEncodingTypeNSMutableData) {
    127                             data = ((NSData *)data).mutableCopy;
    128                         }
    129                         ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, data);
    130                     }
    131                 } break;
    132                     
    133                  // 日期
    134                 case YYEncodingTypeNSDate: {
    135                     if ([value isKindOfClass:[NSDate class]]) {
    136                         ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
    137                     } else if ([value isKindOfClass:[NSString class]]) {
    138                         ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, YYNSDateFromString(value));
    139                     }
    140                 } break;
    141                     
    142                 // NSURL
    143                 case YYEncodingTypeNSURL: {
    144                     if ([value isKindOfClass:[NSURL class]]) {
    145                         ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
    146                     } else if ([value isKindOfClass:[NSString class]]) {
    147                         NSCharacterSet *set = [NSCharacterSet whitespaceAndNewlineCharacterSet];
    148                         NSString *str = [value stringByTrimmingCharactersInSet:set];
    149                         if (str.length == 0) {
    150                             ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, nil);
    151                         } else {
    152                             ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, [[NSURL alloc] initWithString:str]);
    153                         }
    154                     }
    155                 } break;
    156                 
    157                 // 数组
    158                 case YYEncodingTypeNSArray:
    159                 case YYEncodingTypeNSMutableArray: {
    160                     if (meta->_genericCls) {
    161                         NSArray *valueArr = nil;
    162                         if ([value isKindOfClass:[NSArray class]]) valueArr = value;
    163                         else if ([value isKindOfClass:[NSSet class]]) valueArr = ((NSSet *)value).allObjects;
    164                         if (valueArr) {
    165                             NSMutableArray *objectArr = [NSMutableArray new];
    166                             for (id one in valueArr) {
    167                                 if ([one isKindOfClass:meta->_genericCls]) {
    168                                     [objectArr addObject:one];
    169                                 }
    170                                 
    171                                 // 这个把 字段转换成模型了
    172                                 else if ([one isKindOfClass:[NSDictionary class]]) {
    173                                     Class cls = meta->_genericCls;
    174                                     
    175                                     // 这个是 根据字典自定义了返回类型的情况
    176                                     if (meta->_hasCustomClassFromDictionary) {
    177                                         cls = [cls modelCustomClassForDictionary:one];
    178                                         if (!cls) cls = meta->_genericCls; // for xcode code coverage
    179                                     }
    180                                     NSObject *newOne = [cls new];
    181                                     [newOne yy_modelSetWithDictionary:one];
    182                                     if (newOne) [objectArr addObject:newOne];
    183                                 }
    184                             }
    185                             ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, objectArr);
    186                         }
    187                     }
    188                     
    189                     // 处理没有指定数组内部类型的情况,直接把数据转成数组赋值
    190                     else {
    191                         if ([value isKindOfClass:[NSArray class]]) {
    192                             if (meta->_nsType == YYEncodingTypeNSArray) {
    193                                 ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
    194                             } else {
    195                                 ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model,
    196                                                                                meta->_setter,
    197                                                                                ((NSArray *)value).mutableCopy);
    198                             }
    199                         } else if ([value isKindOfClass:[NSSet class]]) {
    200                             if (meta->_nsType == YYEncodingTypeNSArray) {
    201                                 ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, ((NSSet *)value).allObjects);
    202                             } else {
    203                                 ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model,
    204                                                                                meta->_setter,
    205                                                                                ((NSSet *)value).allObjects.mutableCopy);
    206                             }
    207                         }
    208                     }
    209                 } break;
    210                     
    211                 case YYEncodingTypeNSDictionary:
    212                 case YYEncodingTypeNSMutableDictionary: {
    213                     if ([value isKindOfClass:[NSDictionary class]]) {
    214                         if (meta->_genericCls) {
    215                             NSMutableDictionary *dic = [NSMutableDictionary new];
    216                             [((NSDictionary *)value) enumerateKeysAndObjectsUsingBlock:^(NSString *oneKey, id oneValue, BOOL *stop) {
    217                                 if ([oneValue isKindOfClass:[NSDictionary class]]) {
    218                                     Class cls = meta->_genericCls;
    219                                     if (meta->_hasCustomClassFromDictionary) {
    220                                         cls = [cls modelCustomClassForDictionary:oneValue];
    221                                         if (!cls) cls = meta->_genericCls; // for xcode code coverage
    222                                     }
    223                                     NSObject *newOne = [cls new];
    224                                     [newOne yy_modelSetWithDictionary:(id)oneValue];
    225                                     if (newOne) dic[oneKey] = newOne;
    226                                 }
    227                             }];
    228                             ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, dic);
    229                         } else {
    230                             if (meta->_nsType == YYEncodingTypeNSDictionary) {
    231                                 ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
    232                             } else {
    233                                 ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model,
    234                                                                                meta->_setter,
    235                                                                                ((NSDictionary *)value).mutableCopy);
    236                             }
    237                         }
    238                     }
    239                 } break;
    240                     
    241                 case YYEncodingTypeNSSet:
    242                 case YYEncodingTypeNSMutableSet: {
    243                     NSSet *valueSet = nil;
    244                     if ([value isKindOfClass:[NSArray class]]) valueSet = [NSMutableSet setWithArray:value];
    245                     else if ([value isKindOfClass:[NSSet class]]) valueSet = ((NSSet *)value);
    246                     
    247                     if (meta->_genericCls) {
    248                         NSMutableSet *set = [NSMutableSet new];
    249                         for (id one in valueSet) {
    250                             if ([one isKindOfClass:meta->_genericCls]) {
    251                                 [set addObject:one];
    252                             } else if ([one isKindOfClass:[NSDictionary class]]) {
    253                                 Class cls = meta->_genericCls;
    254                                 if (meta->_hasCustomClassFromDictionary) {
    255                                     cls = [cls modelCustomClassForDictionary:one];
    256                                     if (!cls) cls = meta->_genericCls; // for xcode code coverage
    257                                 }
    258                                 NSObject *newOne = [cls new];
    259                                 [newOne yy_modelSetWithDictionary:one];
    260                                 if (newOne) [set addObject:newOne];
    261                             }
    262                         }
    263                         ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, set);
    264                     } else {
    265                         if (meta->_nsType == YYEncodingTypeNSSet) {
    266                             ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, valueSet);
    267                         } else {
    268                             ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model,
    269                                                                            meta->_setter,
    270                                                                            ((NSSet *)valueSet).mutableCopy);
    271                         }
    272                     }
    273                 } // break; commented for code coverage in next line
    274                     
    275                 default: break;
    276             }
    277         }
    278     }
    279     
    280     // 处理既不是c 也不是Foundation 的情况
    281     else {
    282         BOOL isNull = (value == (id)kCFNull);
    283         switch (meta->_type & YYEncodingTypeMask) {
    284             case YYEncodingTypeObject: {
    285                 if (isNull) {
    286                     ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, (id)nil);
    287                 } else if ([value isKindOfClass:meta->_cls] || !meta->_cls) {
    288                     ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, (id)value);
    289                 } else if ([value isKindOfClass:[NSDictionary class]]) {
    290                     NSObject *one = nil;
    291                     if (meta->_getter) {
    292                         one = ((id (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter);
    293                     }
    294                     if (one) {
    295                         [one yy_modelSetWithDictionary:value];
    296                     } else {
    297                         Class cls = meta->_cls;
    298                         if (meta->_hasCustomClassFromDictionary) {
    299                             cls = [cls modelCustomClassForDictionary:value];
    300                             if (!cls) cls = meta->_genericCls; // for xcode code coverage
    301                         }
    302                         one = [cls new];
    303                         [one yy_modelSetWithDictionary:value];
    304                         ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, (id)one);
    305                     }
    306                 }
    307             } break;
    308                 
    309             case YYEncodingTypeClass: {
    310                 if (isNull) {
    311                     ((void (*)(id, SEL, Class))(void *) objc_msgSend)((id)model, meta->_setter, (Class)NULL);
    312                 } else {
    313                     Class cls = nil;
    314                     if ([value isKindOfClass:[NSString class]]) {
    315                         cls = NSClassFromString(value);
    316                         if (cls) {
    317                             ((void (*)(id, SEL, Class))(void *) objc_msgSend)((id)model, meta->_setter, (Class)cls);
    318                         }
    319                     } else {
    320                         cls = object_getClass(value);
    321                         if (cls) {
    322                             if (class_isMetaClass(cls)) {
    323                                 ((void (*)(id, SEL, Class))(void *) objc_msgSend)((id)model, meta->_setter, (Class)value);
    324                             }
    325                         }
    326                     }
    327                 }
    328             } break;
    329                 
    330             case  YYEncodingTypeSEL: {
    331                 if (isNull) {
    332                     ((void (*)(id, SEL, SEL))(void *) objc_msgSend)((id)model, meta->_setter, (SEL)NULL);
    333                 } else if ([value isKindOfClass:[NSString class]]) {
    334                     SEL sel = NSSelectorFromString(value);
    335                     if (sel) ((void (*)(id, SEL, SEL))(void *) objc_msgSend)((id)model, meta->_setter, (SEL)sel);
    336                 }
    337             } break;
    338                 
    339             case YYEncodingTypeBlock: {
    340                 if (isNull) {
    341                     ((void (*)(id, SEL, void (^)()))(void *) objc_msgSend)((id)model, meta->_setter, (void (^)())NULL);
    342                 } else if ([value isKindOfClass:YYNSBlockClass()]) {
    343                     ((void (*)(id, SEL, void (^)()))(void *) objc_msgSend)((id)model, meta->_setter, (void (^)())value);
    344                 }
    345             } break;
    346                 
    347             case YYEncodingTypeStruct:
    348             case YYEncodingTypeUnion:
    349             case YYEncodingTypeCArray: {
    350                 if ([value isKindOfClass:[NSValue class]]) {
    351                     
    352                     // 判断类型是否相同
    353                     const char *valueType = ((NSValue *)value).objCType;
    354                     const char *metaType = meta->_info.typeEncoding.UTF8String;
    355                     if (valueType && metaType && strcmp(valueType, metaType) == 0) {
    356                         [model setValue:value forKey:meta->_name];
    357                     }
    358                 }
    359             } break;
    360                 
    361             case YYEncodingTypePointer:
    362             case YYEncodingTypeCString: {
    363                 if (isNull) {
    364                     ((void (*)(id, SEL, void *))(void *) objc_msgSend)((id)model, meta->_setter, (void *)NULL);
    365                 } else if ([value isKindOfClass:[NSValue class]]) {
    366                     NSValue *nsValue = value;
    367                     if (nsValue.objCType && strcmp(nsValue.objCType, "^v") == 0) {
    368                         ((void (*)(id, SEL, void *))(void *) objc_msgSend)((id)model, meta->_setter, nsValue.pointerValue);
    369                     }
    370                 }
    371             } // break; commented for code coverage in next line
    372                 
    373             default: break;
    374         }
    375     }
    376 }
  • 相关阅读:
    install git on ubuntu
    deploy uwsgi with niginx on ubuntu
    ubuntu下部署solr
    solr relevent project
    20100722
    [Programming Visual C++]Ex05cCScrollView Revisited
    iter_test
    交友类节目
    install scrapy on windows
    20100703
  • 原文地址:https://www.cnblogs.com/machao/p/5590539.html
Copyright © 2011-2022 走看看