本篇主要介绍的是 在真正转之前的几个辅助函数
/** 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 }