本篇主要介绍的是 在真正转之前的几个辅助函数
/**
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 = ;
((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 = ;
((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 = ;
((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];
}
}
这个方法是让用户自己制定 字典内部的返回值类型,如果制定了,在字典转模型的时候,就会按照这个制定的类型进行转换
/**
Set value to model with a property meta. @discussion Caller should hold strong reference to the parameters before this function returns. @param model Should not be nil.
@param value Should not be nil, but can be NSNull.
@param meta Should not be nil, and meta->_setter should not be nil.
*/
static void ModelSetValueForProperty(__unsafe_unretained id model,
__unsafe_unretained id value,
__unsafe_unretained _YYModelPropertyMeta *meta) { /**
* 先判断 是不是c 类型的数据
*/
if (meta->_isCNumber) { /**
* 把 值 转换成 NSnumber
*/
NSNumber *num = YYNSNumberCreateFromID(value); // 设置到 Property 中
ModelSetNumberToProperty(model, num, meta); // 这个不知道是什么意思
if (num) [num class]; // hold the number }
// Foundation 类型
else if (meta->_nsType) { // 如果是kCFNull 就赋值为(id)nil
if (value == (id)kCFNull) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, (id)nil);
} else { // 按照不同的Foundation 类型会有不同的赋值方式
switch (meta->_nsType) {
case YYEncodingTypeNSString:
case YYEncodingTypeNSMutableString: { // value 是字符串或者可变字符串
if ([value isKindOfClass:[NSString class]]) {
if (meta->_nsType == YYEncodingTypeNSString) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
} else {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, ((NSString *)value).mutableCopy);
}
} // value 是 NSNumber 需要根据是不是 可变的进行不同的赋值
else if ([value isKindOfClass:[NSNumber class]]) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model,
meta->_setter,
(meta->_nsType == YYEncodingTypeNSString) ?
((NSNumber *)value).stringValue :
((NSNumber *)value).stringValue.mutableCopy);
}
// value 是NSData
else if ([value isKindOfClass:[NSData class]]) {
NSMutableString *string = [[NSMutableString alloc] initWithData:value encoding:NSUTF8StringEncoding];
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, string);
} // value 是NSURL
else if ([value isKindOfClass:[NSURL class]]) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model,
meta->_setter,
(meta->_nsType == YYEncodingTypeNSString) ?
((NSURL *)value).absoluteString :
((NSURL *)value).absoluteString.mutableCopy);
}
// value 是带属性的字符串
else if ([value isKindOfClass:[NSAttributedString class]]) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model,
meta->_setter,
(meta->_nsType == YYEncodingTypeNSString) ?
((NSAttributedString *)value).string :
((NSAttributedString *)value).string.mutableCopy);
}
} break; case YYEncodingTypeNSValue:
case YYEncodingTypeNSNumber:
case YYEncodingTypeNSDecimalNumber: {
if (meta->_nsType == YYEncodingTypeNSNumber) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, YYNSNumberCreateFromID(value));
} // 科学计数值 这里判断了3种情况,需要更具不同的情况转化为NSDecimalNumber
else if (meta->_nsType == YYEncodingTypeNSDecimalNumber) {
if ([value isKindOfClass:[NSDecimalNumber class]]) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
} else if ([value isKindOfClass:[NSNumber class]]) {
NSDecimalNumber *decNum = [NSDecimalNumber decimalNumberWithDecimal:[((NSNumber *)value) decimalValue]];
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, decNum);
} else if ([value isKindOfClass:[NSString class]]) {
NSDecimalNumber *decNum = [NSDecimalNumber decimalNumberWithString:value];
NSDecimal dec = decNum.decimalValue;
if (dec._length == && dec._isNegative) {
decNum = nil; // NaN
}
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, decNum);
}
} else { // YYEncodingTypeNSValue
if ([value isKindOfClass:[NSValue class]]) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
}
}
} break; // 一般NSData 有两种标示,一种是NSData 一种是NSString ,但最终都需要转换成NSData或者NSMutableData
case YYEncodingTypeNSData:
case YYEncodingTypeNSMutableData: {
if ([value isKindOfClass:[NSData class]]) {
if (meta->_nsType == YYEncodingTypeNSData) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
} else {
NSMutableData *data = ((NSData *)value).mutableCopy;
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, data);
}
} else if ([value isKindOfClass:[NSString class]]) {
NSData *data = [(NSString *)value dataUsingEncoding:NSUTF8StringEncoding];
if (meta->_nsType == YYEncodingTypeNSMutableData) {
data = ((NSData *)data).mutableCopy;
}
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, data);
}
} break; // 日期
case YYEncodingTypeNSDate: {
if ([value isKindOfClass:[NSDate class]]) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
} else if ([value isKindOfClass:[NSString class]]) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, YYNSDateFromString(value));
}
} break; // NSURL
case YYEncodingTypeNSURL: {
if ([value isKindOfClass:[NSURL class]]) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
} else if ([value isKindOfClass:[NSString class]]) {
NSCharacterSet *set = [NSCharacterSet whitespaceAndNewlineCharacterSet];
NSString *str = [value stringByTrimmingCharactersInSet:set];
if (str.length == ) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, nil);
} else {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, [[NSURL alloc] initWithString:str]);
}
}
} break; // 数组
case YYEncodingTypeNSArray:
case YYEncodingTypeNSMutableArray: {
if (meta->_genericCls) {
NSArray *valueArr = nil;
if ([value isKindOfClass:[NSArray class]]) valueArr = value;
else if ([value isKindOfClass:[NSSet class]]) valueArr = ((NSSet *)value).allObjects;
if (valueArr) {
NSMutableArray *objectArr = [NSMutableArray new];
for (id one in valueArr) {
if ([one isKindOfClass:meta->_genericCls]) {
[objectArr addObject:one];
} // 这个把 字段转换成模型了
else if ([one isKindOfClass:[NSDictionary class]]) {
Class cls = meta->_genericCls; // 这个是 根据字典自定义了返回类型的情况
if (meta->_hasCustomClassFromDictionary) {
cls = [cls modelCustomClassForDictionary:one];
if (!cls) cls = meta->_genericCls; // for xcode code coverage
}
NSObject *newOne = [cls new];
[newOne yy_modelSetWithDictionary:one];
if (newOne) [objectArr addObject:newOne];
}
}
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, objectArr);
}
} // 处理没有指定数组内部类型的情况,直接把数据转成数组赋值
else {
if ([value isKindOfClass:[NSArray class]]) {
if (meta->_nsType == YYEncodingTypeNSArray) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
} else {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model,
meta->_setter,
((NSArray *)value).mutableCopy);
}
} else if ([value isKindOfClass:[NSSet class]]) {
if (meta->_nsType == YYEncodingTypeNSArray) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, ((NSSet *)value).allObjects);
} else {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model,
meta->_setter,
((NSSet *)value).allObjects.mutableCopy);
}
}
}
} break; case YYEncodingTypeNSDictionary:
case YYEncodingTypeNSMutableDictionary: {
if ([value isKindOfClass:[NSDictionary class]]) {
if (meta->_genericCls) {
NSMutableDictionary *dic = [NSMutableDictionary new];
[((NSDictionary *)value) enumerateKeysAndObjectsUsingBlock:^(NSString *oneKey, id oneValue, BOOL *stop) {
if ([oneValue isKindOfClass:[NSDictionary class]]) {
Class cls = meta->_genericCls;
if (meta->_hasCustomClassFromDictionary) {
cls = [cls modelCustomClassForDictionary:oneValue];
if (!cls) cls = meta->_genericCls; // for xcode code coverage
}
NSObject *newOne = [cls new];
[newOne yy_modelSetWithDictionary:(id)oneValue];
if (newOne) dic[oneKey] = newOne;
}
}];
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, dic);
} else {
if (meta->_nsType == YYEncodingTypeNSDictionary) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, value);
} else {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model,
meta->_setter,
((NSDictionary *)value).mutableCopy);
}
}
}
} break; case YYEncodingTypeNSSet:
case YYEncodingTypeNSMutableSet: {
NSSet *valueSet = nil;
if ([value isKindOfClass:[NSArray class]]) valueSet = [NSMutableSet setWithArray:value];
else if ([value isKindOfClass:[NSSet class]]) valueSet = ((NSSet *)value); if (meta->_genericCls) {
NSMutableSet *set = [NSMutableSet new];
for (id one in valueSet) {
if ([one isKindOfClass:meta->_genericCls]) {
[set addObject:one];
} else if ([one isKindOfClass:[NSDictionary class]]) {
Class cls = meta->_genericCls;
if (meta->_hasCustomClassFromDictionary) {
cls = [cls modelCustomClassForDictionary:one];
if (!cls) cls = meta->_genericCls; // for xcode code coverage
}
NSObject *newOne = [cls new];
[newOne yy_modelSetWithDictionary:one];
if (newOne) [set addObject:newOne];
}
}
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, set);
} else {
if (meta->_nsType == YYEncodingTypeNSSet) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, valueSet);
} else {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model,
meta->_setter,
((NSSet *)valueSet).mutableCopy);
}
}
} // break; commented for code coverage in next line default: break;
}
}
} // 处理既不是c 也不是Foundation 的情况
else {
BOOL isNull = (value == (id)kCFNull);
switch (meta->_type & YYEncodingTypeMask) {
case YYEncodingTypeObject: {
if (isNull) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, (id)nil);
} else if ([value isKindOfClass:meta->_cls] || !meta->_cls) {
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, (id)value);
} else if ([value isKindOfClass:[NSDictionary class]]) {
NSObject *one = nil;
if (meta->_getter) {
one = ((id (*)(id, SEL))(void *) objc_msgSend)((id)model, meta->_getter);
}
if (one) {
[one yy_modelSetWithDictionary:value];
} else {
Class cls = meta->_cls;
if (meta->_hasCustomClassFromDictionary) {
cls = [cls modelCustomClassForDictionary:value];
if (!cls) cls = meta->_genericCls; // for xcode code coverage
}
one = [cls new];
[one yy_modelSetWithDictionary:value];
((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, meta->_setter, (id)one);
}
}
} break; case YYEncodingTypeClass: {
if (isNull) {
((void (*)(id, SEL, Class))(void *) objc_msgSend)((id)model, meta->_setter, (Class)NULL);
} else {
Class cls = nil;
if ([value isKindOfClass:[NSString class]]) {
cls = NSClassFromString(value);
if (cls) {
((void (*)(id, SEL, Class))(void *) objc_msgSend)((id)model, meta->_setter, (Class)cls);
}
} else {
cls = object_getClass(value);
if (cls) {
if (class_isMetaClass(cls)) {
((void (*)(id, SEL, Class))(void *) objc_msgSend)((id)model, meta->_setter, (Class)value);
}
}
}
}
} break; case YYEncodingTypeSEL: {
if (isNull) {
((void (*)(id, SEL, SEL))(void *) objc_msgSend)((id)model, meta->_setter, (SEL)NULL);
} else if ([value isKindOfClass:[NSString class]]) {
SEL sel = NSSelectorFromString(value);
if (sel) ((void (*)(id, SEL, SEL))(void *) objc_msgSend)((id)model, meta->_setter, (SEL)sel);
}
} break; case YYEncodingTypeBlock: {
if (isNull) {
((void (*)(id, SEL, void (^)()))(void *) objc_msgSend)((id)model, meta->_setter, (void (^)())NULL);
} else if ([value isKindOfClass:YYNSBlockClass()]) {
((void (*)(id, SEL, void (^)()))(void *) objc_msgSend)((id)model, meta->_setter, (void (^)())value);
}
} break; case YYEncodingTypeStruct:
case YYEncodingTypeUnion:
case YYEncodingTypeCArray: {
if ([value isKindOfClass:[NSValue class]]) { // 判断类型是否相同
const char *valueType = ((NSValue *)value).objCType;
const char *metaType = meta->_info.typeEncoding.UTF8String;
if (valueType && metaType && strcmp(valueType, metaType) == ) {
[model setValue:value forKey:meta->_name];
}
}
} break; case YYEncodingTypePointer:
case YYEncodingTypeCString: {
if (isNull) {
((void (*)(id, SEL, void *))(void *) objc_msgSend)((id)model, meta->_setter, (void *)NULL);
} else if ([value isKindOfClass:[NSValue class]]) {
NSValue *nsValue = value;
if (nsValue.objCType && strcmp(nsValue.objCType, "^v") == ) {
((void (*)(id, SEL, void *))(void *) objc_msgSend)((id)model, meta->_setter, nsValue.pointerValue);
}
}
} // break; commented for code coverage in next line default: break;
}
}
}
YYModel 源码解读(二)之NSObject+YYModel.h (3)的更多相关文章
-
YYModel 源码解读(二)之NSObject+YYModel.h (1)
本篇文章主要介绍 _YYModelPropertyMeta 前边的内容 首先先解释一下前边的辅助函数和枚举变量,在写一个功能的时候,这些辅助的东西可能不是一开始就能想出来的,应该是在后续的编码过程中 ...
-
jQuery.Callbacks 源码解读二
一.参数标记 /* * once: 确保回调列表仅只fire一次 * unique: 在执行add操作中,确保回调列表中不存在重复的回调 * stopOnFalse: 当执行回调返回值为false,则 ...
-
(转)go语言nsq源码解读二 nsqlookupd、nsqd与nsqadmin
转自:http://www.baiyuxiong.com/?p=886 ---------------------------------------------------------------- ...
-
YYModel 源码解读(二)之YYClassInfo.h (3)
前边3篇介绍了YYClassinfo 文件的组成单元,算是功能的分割,按照业务的设计思想来说,方向应该是相反的 由此引申出我们在设计api的思想其实和项目管理是很类似的----- 一些题外话 1.目的 ...
-
YYModel 源码解读 总结
在使用swfit写代码的过程中,使用了下oc写的字典转模型,发现有些属性转不成功,就萌生了阅读源码的想法. 其实一直都知道Runtime机制,但并没有系统的学习,可能是因为平时的使用比较少,无意间在g ...
-
YYModel 源码解读(一)之YYModel.h
#if __has_include(<YYModel/YYModel.h>) FOUNDATION_EXPORT double YYModelVersionNumber; FOUNDATI ...
-
mybatis源码解读(二)——构建Configuration对象
Configuration 对象保存了所有mybatis的配置信息,主要包括: ①. mybatis-configuration.xml 基础配置文件 ②. mapper.xml 映射器配置文件 1. ...
-
ConcurrentHashMap源码解读二
接下来就讲解put里面的三个方法,分别是 1.数组初始化方法initTable() 2.线程协助扩容方法helpTransfer() 3.计数方法addCount() 首先是数组初始化,再将源码之前, ...
-
go语言nsq源码解读二 nsqlookupd、nsqd与nsqadmin
nsqlookupd: 官方文档解释见:http://bitly.github.io/nsq/components/nsqlookupd.html 用官方话来讲是:nsqlookupd管理拓扑信息,客 ...
-
vue2.0 源码解读(二)
小伞最近比较忙,阅读源码的速度越来越慢了 最近和朋友交流的时候,发现他们对于源码的目录结构都不是很清楚 红色圈子内是我们需要关心的地方 compiler 模板编译部分 core 核心实现部分 ent ...
随机推荐
-
BruteXSS:XSS暴力破解神器
×01 BruteXSS BruteXSS是一个非常强大和快速的跨站点脚本暴力注入.它用于暴力注入一个参数.该BruteXSS从指定的词库加载多种有效载荷进行注入并且使用指定的载荷和扫描检查这些参数很 ...
-
WCF的三个名称/命名空间,你是否傻傻分不清楚?
在定义和寄宿WCF服务的时候会面临三个名称/命名空间,它们分别是ServiceContractAttribute.ServiceBehaviorAttribute和Binding的Name和Names ...
-
iOS-CALayer
iOS开发UI篇—CAlayer层的属性 一.position和anchorPoint 1.简单介绍 CALayer有2个非常重要的属性:position和anchorPoint @property ...
-
poj 2068 Nim 博弈论
思路:dp[i][j]:第i个人时还剩j个石头. 当j为0时,有必胜为1: 后继中有必败态的为必胜态!!记忆化搜索下就可以了! 代码如下: #include<iostream> #incl ...
-
disucz!NT 3.5.0 验证码点击不能变化只是样式变化
来博客园这么久了,第一次写博客啊!公司有个论坛10年没动了,是discuz!NT 3.5.0版本的,由于验证码不能变化老是被人刷.网上找了很多资料根本没有.可能有同行下次也会遇到这样的问题,我就把我的 ...
-
buffer busy wait在RAC环境下出现
昨天运维组的同时反映有套系统用户反映很慢,需要协助帮忙检查什么原因引起的性能问题.导出了从8点到11点的AWR报告进行分析,发现等待事件里大部分的指标都正常,就是buffer busy wait的平均 ...
-
Eclipse 常用快捷键 (动画讲解)(转载)
http://www.cnblogs.com/TankXiao/p/4018219.html#fix 很详细呀/
-
面向对象程序设计-C++_课时22向上造型
赋值兼容规则是指在公有派生情况下,一个派生类的对象可以作为基类的对象来使用的情况. 约定类derived是从类base公有派生而来的,则指如下3种情况: (1)派生的对象可以赋给基类的对象.例如: d ...
-
LPC 网络编程
LPC有五种不同的通信模式(socket模式) ① MUD (面向连接的通信模式) 可以把除Object以外的所有LPC模型从一个MUD传到另一个MUD 弊端: 无法传送物件造成了穿越MUD的功能(即 ...
-
SpringBoot学习(三)-->;Spring的Java配置方式之读取外部的资源配置文件并配置数据库连接池
三.读取外部的资源配置文件并配置数据库连接池 1.读取外部的资源配置文件 通过@PropertySource可以指定读取的配置文件,通过@Value注解获取值,具体用法: @Configuration ...