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 }
原文地址:https://www.cnblogs.com/machao/p/5590539.html